
    gV                        d dl mZ d dlmZ ddlZddlZddlZddlZddlmZm	Z	 ej                  dk\  rddlmZmZmZmZ nddlmZmZmZmZ  ej(                  e      Zdddddddddddd	Zdddddddddd
	Zdddddiddddddddddddddddddd
	dd d!d"
d#d$d%dd&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5dd6d"
d7Z G d8 d9      Zy):   )NetError)unique_everseen    N)datetime	timedelta)   r   )
ip_address
ip_networksummarize_address_rangecollapse_addresses)	IPAddress	IPNetworkr   collapse_address_list)cidrnamehandlerangecountryaddresspostal_codenameserverscreatedupdatedcontacts)	r   emailreply_emailorganizationdivisiontitlephonefaxr   JPzFhttp://whois.nic.ad.jp/cgi-bin/whois_gw?lang=%2Fe&key={0}&submit=queryGETAcceptz	text/htmlz((\[Organization\])[^\S\n]+(?P<val>.*?)\nz((\[Network Name\])[^\S\n]+(?P<val>.*?)\nz)(\[Assigned Date\])[^\S\n]+(?P<val>.*?)\nz'(\[Last Update\])[^\S\n]+(?P<val>.*?)\nz&(\[Nameserver\])[^\S\n]+(?P<val>.*?)\nz=(\[Administrative Contact\])[^\S\n]+.+?\>(?P<val>.+?)\<\/A\>
z8(\[Technical Contact\])[^\S\n]+.+?\>(?P<val>.+?)\<\/A\>
)r   r   r   r   r   contact_admincontact_techz'(\[Last, First\])[^\S\n]+(?P<val>.*?)\nz"(\[E-Mail\])[^\S\n]+(?P<val>.*?)\nz&(\[Reply Mail\])[^\S\n]+(?P<val>.*?)\nz$(\[Division\])[^\S\n]+(?P<val>.*?)\nz!(\[Title\])[^\S\n]+(?P<val>.*?)\nz(\[TEL\])[^\S\n]+(?P<val>.*?)\nz(\[FAX\])[^\S\n]+(?P<val>.*?)\nz%Y/%m/%d %H:%M:%S(JST)	   F)
country_codeurlrequest_typerequest_headersform_data_ip_fieldfieldscontact_fields	dt_formatdt_hourdelta	multi_netKRz8https://xn--c79as89aj0e29b77z.xn--3e0b707e/eng/whois.jscPOSTz8https://xn--c79as89aj0e29b77z.xn--3e0b707e/eng/whois.jsp)r$   Refererqueryz0(Organization Name)[\s]+\:[^\S\n]+(?P<val>.+?)\nz7(Service Name|Network Type)[\s]+\:[^\S\n]+(?P<val>.+?)
z&(Address)[\s]+\:[^\S\n]+(?P<val>.+?)\nz'(Zip Code)[\s]+\:[^\S\n]+(?P<val>.+?)\nz0(Registration Date)[\s]+\:[^\S\n]+(?P<val>.+?)\nz1(id="eng_isp_contact").+?\>(?P<val>.*?)\<\/div\>
z2(id="eng_user_contact").+?\>(?P<val>.*?)\<\/div\>
)r   r   r   r   r   r%   r&   z'(Name)[^\S\n]+?:[^\S\n]+?(?P<val>.*?)\nz)(E-Mail)[^\S\n]+?:[^\S\n]+?(?P<val>.*?)\nz((Phone)[^\S\n]+?:[^\S\n]+?(?P<val>.*?)\n)r   r   r    z%Y%m%dT)jpnickrnicc                   H    e Zd ZdZd Z	 	 	 d	dZd Zd Z	 	 d
dZ	 	 ddZ	y)NIRWhoisa  
    The class for parsing whois data for NIRs (National Internet Registry).
    JPNIC and KRNIC are currently the only NIRs supported. Output varies
    based on NIR specific whois formatting.

    Args:
        net (:obj:`ipwhois.net.Net`): The network object.

    Raises:
        NetError: The parameter provided is not an instance of
            ipwhois.net.Net
        IPDefinedError: The address provided is defined (does not need to be
            resolved).
    c                 L    ddl m} t        ||      r|| _        y t	        d      )Nr   )Netz@The provided net parameter is not an instance of ipwhois.net.Net)netr;   
isinstance_netr   )selfr<   r;   s       /opt/Tautulli/lib/ipwhois/nir.py__init__zNIRWhois.__init__   s,     c3DI  - . .    Nc	                    dj                  |      }|r"i }	syt        t        j                               n[dddi i d}	sPt        t        j                               j                  d       j                  d       j                  d       fd|j                         D        }
|
D ]9  \  }}t        j                  t        |      t        j                        }||j                  |||      }n&||j                  ||      }n|j                  |      }g }|D ]1  }	 |j                  |j                  d	      j                                3 t!        |      d
kD  sd}	 |dv rB|r@	 t#        j$                  |d
   t        |            t'        |      z
  j)                  d      }n5|dv rt        t-        |            }nt-        |      }dj/                  |      }||	|<   < |	S # t        $ r Y w xY w# t*        $ r+ t#        j$                  |d
   d      j)                  d      }Y Lw xY w# t*        $ r/}t0        j3                  dj                  ||             Y d}~d}~ww xY w)a	  
        The function for parsing whois fields from a data input.

        Args:
            response (:obj:`str`): The response from the whois/rwhois server.
            fields_dict (:obj:`dict`): The mapping of fields to regex search
                values (required).
            net_start (:obj:`int`): The starting point of the network (if
                parsing multiple networks). Defaults to None.
            net_end (:obj:`int`): The ending point of the network (if parsing
                multiple networks). Defaults to None.
            dt_format (:obj:`str`): The format of datetime fields if known.
                Defaults to None.
            field_list (:obj:`list` of :obj:`str`): If provided, fields to
                parse. Defaults to :obj:`ipwhois.nir.BASE_NET` if is_contact
                is False. Otherwise, defaults to
                :obj:`ipwhois.nir.BASE_CONTACT`.
            hourdelta (:obj:`int`): The timezone delta for created/updated
                fields. Defaults to 0.
            is_contact (:obj:`bool`): If True, uses contact information
                field parsing. Defaults to False.

        Returns:
            dict: A dictionary of fields provided in fields_dict, mapping to
                the results of the regex searches.
        z{0}
Nadmintech)r   r%   r&   r   r%   r&   c              3   4   K   | ]  \  }}|v r||f  y w)N ).0fieldpattern
field_lists      r@   	<genexpr>z(NIRWhois.parse_fields.<locals>.<genexpr>   s,      @)9%+0J+> G$ @s   valr   )r   r   )hoursTz%Y/%m/%d)r   
z+NIR whois field parsing failed for {0}: {1})formatlistBASE_CONTACTkeysBASE_NETremoveappenditemsrecompilestrDOTALLfinditergroupstrip
IndexErrorlenr   strptimer   	isoformat
ValueErrorr   joinlogdebug)r?   responsefields_dict	net_startnet_endr/   rL   	hourdelta
is_contactretgeneraterJ   rK   matchvaluesmvaluees         `           r@   parse_fieldszNIRWhois.parse_fields   sw   < >>(+C!,"3"3"56

 '+D9!# "C !(--/2
!!*-!!/2!!.1@%%'@ ' C	#NE7jjG		G
 $((7IF$((7;  ((2F MM!''%."6"6"89	 6{Q  669- ( 1 1$*1I$'	N!" %.I$>!? (in " /1 $_V%< = "1!8 $		& 1 #E
GC	#J 
W " $  * - ( 1 1$*1I$.!" (in "-" " II !!'q!13	sN   %.G,'H2.>G;,6H2,	G87G8;1H/,H2.H//H22	I*;%I%%I*c                    g }t        j                  d|t         j                        D ]  }	 t        j                  t
              }t        |j                  d            }	 |j                  }	 |j                  }dj                  |dz   |      |d<   t        |j                  d      j                               j                         }||d<   |j!                         |d<   |j#                         |d<   |j%                  |        |S # t        $ r |j                  }Y w xY w# t        $ r |j                  }Y w xY w# t&        t(        f$ r Y 'w xY w)	a  
        The function for parsing network blocks from jpnic whois data.

        Args:
            response (:obj:`str`): The response from the jpnic server.

        Returns:
            list of dict: Mapping of networks with start and end positions.

            ::

                [{
                    'cidr' (str) - The network routing block
                    'start' (int) - The starting point of the network
                    'end' (int) - The endpoint point of the network
                }]
        z5^.*?(\[Network Number\])[^\S\n]+.+?>(?P<val>.+?)</A>$   	{0} - {1}r   r   r   startend)rZ   r^   	MULTILINEcopydeepcopyrV   r
   r_   network_addressAttributeErroripbroadcast_address	broadcastrR   r`   __str__rz   r{   rX   re   	TypeError)	r?   ri   netsrq   r<   tmpr   r   r   s	            r@   get_nets_jpniczNIRWhois.get_nets_jpnic.  sK   &  [[H
 $	EmmH- Q0&)&9&9O
(+(=(=%
  +11#a'): G "%++a."6"6"89AAC"F${{}G"YY[E
C A$	L 3 & &)ffO & (+% 	* sT   3D= D-D"9B
D=DD=DD="D:7D=9D::D==EEc                    g }t        j                  d|t         j                        D ]  }	 t        j                  t
              }|j                  d      |d<   |j                  d      r|j                  d      rg }|j                  t        t        |j                  d      j                               t        |j                  d      j                                            dj                  t        |      D cg c]  }|j                          c}      }dj                  |j                  d      |j                  d            |d<   n6t        |j                  d      j                               j                         }||d<   |j!                         |d	<   |j#                         |d
<   |j%                  |        |S c c}w # t&        t(        f$ r Y w xY w)a  
        The function for parsing network blocks from krnic whois data.

        Args:
            response (:obj:`str`): The response from the krnic server.

        Returns:
            list of dict: Mapping of networks with start and end positions.

            ::

                [{
                    'cidr' (str) - The network routing block
                    'start' (int) - The starting point of the network
                    'end' (int) - The endpoint point of the network
                }]
        zK^(IPv4 Address)[\s]+:[^\S\n]+((.+?)[^\S\n]-[^\S\n](.+?)[^\S
]\((.+?)\)|.+)$rx   r   r      z, ry   r   rz   r{   )rZ   r^   r|   r}   r~   rV   r_   extendr   r	   r`   rf   r   r   rR   r
   rz   r{   rX   re   r   )r?   ri   r   rq   r<   addrsir   s           r@   get_nets_krniczNIRWhois.get_nets_krnicm  s   &  [[+	
 &	EmmH-${{1~G;;q>ekk!nELL!8"5;;q>#7#7#9:"5;;q>#7#7#9:"< =  99.@.GHHD $/#5#5AA$CL &ekk!n&:&:&<=EEGD"F${{}G"YY[E
C E&	P ) I  	* s%   CG=G
B-GGGGc           	      &   |s|dk(  r|}nU| j                   j                  t        t        |   d         j	                  |      |t        |   d   t        |   d         }| j                  |t        |   d   |t        t        |   d         d	      S )
a  
        The function for retrieving and parsing NIR whois data based on
        NIR_WHOIS contact_fields.

        Args:
            response (:obj:`str`): Optional response object, this bypasses the
                lookup.
            nir (:obj:`str`): The NIR to query ('jpnic' or 'krnic'). Required
                if response is None.
            handle (:obj:`str`): For NIRs that have separate contact queries
                (JPNIC), this is the contact handle to use in the query.
                Defaults to None.
            retry_count (:obj:`int`): The number of times to retry in case
                socket errors, timeouts, connection resets, etc. are
                encountered. Defaults to 3.
            dt_format (:obj:`str`): The format of datetime fields if known.
                Defaults to None.

        Returns:
            dict: Mapping of the fields provided in contact_fields, to their
                parsed results.
        r7   r)   r+   r*   )r)   retry_countheadersr*   r.   r0   T)ri   rj   r/   rm   rn   )r>   get_http_rawr\   	NIR_WHOISrR   rv   int)r?   ri   nirr   r   r/   contact_responses          r@   get_contactzNIRWhois.get_contact  s    2 sg~'
  $yy55	#u-.55f='!#'89&s^N;	  6     %!#'78)C.89 ! 
 	
rB   c                    |t         j                         vrt        d      | j                  j                  dd}||rt        d      t
        j                  dj                  | j                  j                               d}t         |   d   r"t         |   d   | j                  j                  i}| j                  j                  t        t         |   d         j                  | j                  j                        |t         |   d   t         |   d	   |
      }|r||d<   g }	d}
|dk(  r| j                  |      }
n|dk(  r| j                  |      }
|	j                  |
       i }t
        j                  d       t        |	      D ]C  \  }}d}|dz   t        |	      k  r|	|dz      d   }	 t         |   d   }| j                  |t         |   d   ||d   ||t!        t         |   d               }t         |   d   |d<   |d   |d   d}|d= |d= |s|j#                         D ]  \  }}t        |      dkD  st%        |t              r|j'                         }|D ]U  }||j                         v r||   |d   |<   !|dk(  r|}d}nd}|}| j)                  |||||      |d   |<   |d   |   ||<   W  |j+                  |       |d= |d= F |	|d<   |S # t        $ r d}Y *w xY w)a  
        The function for retrieving and parsing NIR whois information for an IP
        address via HTTP (HTML scraping).

        Args:
            nir (:obj:`str`): The NIR to query ('jpnic' or 'krnic'). Required
                if response is None.
            inc_raw (:obj:`bool`, optional): Whether to include the raw
                results in the returned dictionary. Defaults to False.
            retry_count (:obj:`int`): The number of times to retry in case
                socket errors, timeouts, connection resets, etc. are
                encountered. Defaults to 3.
            response (:obj:`str`): Optional response object, this bypasses the
                NIR lookup. Required when is_offline=True.
            field_list (:obj:`list` of :obj:`str`): If provided, fields to
                parse. Defaults to :obj:`ipwhois.nir.BASE_NET`.
            is_offline (:obj:`bool`): Whether to perform lookups offline. If
                True, response and asn_data must be provided. Primarily used
                for testing.

        Returns:
            dict: The NIR whois results:

            ::

                {
                    'query' (str) - The IP address.
                    'nets' (list of dict) - Network information which consists
                        of the fields listed in the ipwhois.nir.NIR_WHOIS
                        dictionary.
                    'raw' (str) - Raw NIR whois results if the inc_raw
                        parameter is True.
                }
        z/Invalid arg for nir (National Internet RegistryN)r5   rawz/response argument required when is_offline=Truez0Response not given, perform WHOIS lookup for {0}r,   r)   r+   r*   )r)   r   r   r*   	form_datar   r6   r7   zParsing NIR WHOIS datar   rz   r/   r-   r{   r0   )ri   rj   rk   rl   r/   rL   rm   r(   r   r%   r&   rD   r   r   )ri   r   r   r   r/   r   )r   rU   KeyErrorr>   address_strrg   rh   rR   r   r\   r   r   r   	enumeraterb   rv   r   rY   r=   
splitlinesr   update)r?   r   inc_rawr   ri   rL   
is_offlineresultsr   r   nets_responseglobal_contactsindexr<   section_endr/   temp_netr   keyrN   contacttmp_response
tmp_handles                          r@   lookupzNIRWhois.lookup  su   J inn&&LMM YY**
   1 2 2 IIHvdii3346 I~23&s^,@A!YY224	 yy--	#u-.55dii6K6KL'!#'89&s^N;# . H %GEN'> //9MG^ //9MM" 			*+#D/ O	)JE3Kqy3t9$"519og6!%cN;7	 ((!%cN84%E
#%in^<= ) H #,C."@HY!/2 0H )(  ( 0 %"HC3x!|%c3/"%.."2C'* "G&/*>*>*@@ %4G$< !) 4S 9 $''>3:L15J 48L18J<@<L<L-9+5(+0;.7 =M =" 4S 9 %-Z$8$= !0 87"%"P JJx  Gc%j_O	)d U  ! 	!s   -KK$#K$)NNNNr   F)NNNr   N)NFr   NNF)
__name__
__module____qualname____doc__rA   rv   r   r   r   r   rH   rB   r@   r9   r9      sI    . =A>B-2~@=~?B ;?-1-
^ GK+0rrB   r9   ) r   utilsr   loggingsysrZ   r}   r   r   version_info	ipaddressr	   r
   r   r   ipaddrr   r   r   	getLoggerr   rg   rV   rT   r   r9   rH   rB   r@   <module>r      s|  2  "  
 	  *v/ /
E E
 g!   
  $k2"?ACAD88

 ?:DG?975A

 .? D I!J
 &G@EJ,+
 ?A@

 =EB	J rB   