o
    CD©i:  ã                   @   sv   d dl Z d dlZd dlZd dlZd dlZd dlmZmZ d dlm	Z	 ddl
mZ G dd„ deƒZG dd	„ d	e	eƒZdS )
é    N)ÚreactorÚdefer)ÚDatagramProtocolé   )ÚNBNSc                   @   s   e Zd ZdZdS )ÚNetBIOSTimeoutzfRaised in NBNSProtocol via Deferred.errback method when queryName method has timeout waiting for replyN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__© r   r   úL/var/www/Datamplify/venv/lib/python3.10/site-packages/nmb/NetBIOSProtocol.pyr      s    r   c                   @   sT   e Zd Ze d¡Zddd„Zdd„ Zdd	„ Zddd„Z	ddd„Z
dd„ Zdd„ ZdS )ÚNBNSProtocolzNMB.NBNSProtocolTr   c                 C   sJ   || _ i | _t || ¡| _| j r| j ¡  tjtj	d¡ t 
d| j¡ dS )aß  
        Instantiate a NBNSProtocol instance.

        This automatically calls reactor.listenUDP method to start listening for incoming packets, so you **must not** call the listenUDP method again.

        :param boolean broadcast: A boolean flag to indicate if we should setup the listening UDP port in broadcast mode
        :param integer listen_port: Specifies the UDP port number to bind to for listening. If zero, OS will automatically select a free port number.
        r   N)Ú	broadcastÚpending_trnsr   Ú	listenUDPÚ	transportÚ	getHandleÚ
setsockoptÚsocketÚ
SOL_SOCKETÚSO_BROADCASTÚ	callLaterÚcleanupPendingTrns)Úselfr   Úlisten_portr   r   r   Ú__init__   s   	zNBNSProtocol.__init__c           
      C   sZ   |\}}|   |¡\}}|| jv r+| j |¡\}}}	|tu r$|  |¡\}}|	 |¡ d S d S ©N)ÚdecodePacketr   ÚpopÚ
NAME_QUERYÚdecodeIPQueryPacketÚcallback)
r   ÚdataÚ	from_infoÚhostÚportÚtrn_idÚretÚ_ÚipÚdr   r   r   ÚdatagramReceived   s   
ûzNBNSProtocol.datagramReceivedc                 C   s   | j  ¡  |||f¡ d S r   )r   r   Úsendto)r   r#   r*   r&   r   r   r   Úwrite+   s   zNBNSProtocol.writeÚ é‰   é   c                 C   s†   t  dd¡}	 || jvrn|d d@ }q|  ||¡}| jr"|s"d}n|s*| j d¡ |  |||¡ t 	¡ }t
 
¡ | ||f| j|< |S )aX  
        Send a query on the network and hopes that if machine matching the *name* will reply with its IP address.

        :param string ip: If the NBNSProtocol instance was instianted with broadcast=True, then this parameter can be an empty string. We will leave it to the OS to determine an appropriate broadcast address.
                          If the NBNSProtocol instance was instianted with broadcast=False, then you should provide a target IP to send the query.
        :param integer port: The NetBIOS-NS port (IANA standard defines this port to be 137). You should not touch this parameter unless you know what you are doing.
        :param integer/float timeout: Number of seconds to wait for a reply, after which the returned Deferred instance will be called with a NetBIOSTimeout exception.
        :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with a list of IP addresses in dotted notation (aaa.bbb.ccc.ddd).
                 On timeout, the errback function will be called with a Failure instance wrapping around a NetBIOSTimeout exception
        r   éÿÿ  Tz<broadcast>zQqueryName: ip parameter is empty. OS might not transmit this query to the network)ÚrandomÚrandintr   ÚprepareNameQueryr   ÚlogÚwarningr.   r   ÚDeferredÚtime)r   Únamer*   r&   Útimeoutr'   r#   r+   r   r   r   Ú	queryName/   s   
ü
zNBNSProtocol.queryNamec                    sŽ   t  dd¡}	 || jvrn|d d@ }q|  |¡}|  |||¡ t ¡ ‰ t ¡ }| ˆ j¡ ‡ fdd„}| 	|¡ t
 
¡ | t|f| j|< ˆ S )aU  
        Send a query to the machine with *ip* and hopes that the machine will reply back with its name.

        The implementation of this function is contributed by Jason Anderson.

        :param string ip: If the NBNSProtocol instance was instianted with broadcast=True, then this parameter can be an empty string. We will leave it to the OS to determine an appropriate broadcast address.
                          If the NBNSProtocol instance was instianted with broadcast=False, then you should provide a target IP to send the query.
        :param integer port: The NetBIOS-NS port (IANA standard defines this port to be 137). You should not touch this parameter unless you know what you are doing.
        :param integer/float timeout: Number of seconds to wait for a reply, after which the method will return None
        :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with a list of names of the machine at *ip*.
                 On timeout, the errback function will be called with a Failure instance wrapping around a NetBIOSTimeout exception
        r   r2   Tc                    s.   | d urˆ   tdd„ tdd„ | ƒƒ¡ d S d S )Nc                 S   s   | d S ©Nr   r   ©Úsr   r   r   Ú<lambda>j   s    z@NBNSProtocol.queryIPForName.<locals>.stripCode.<locals>.<lambda>c                 S   s   | d t kS )Nr   )ÚTYPE_SERVERr>   r   r   r   r@   j   ó    )r"   ÚmapÚfilter)r(   ©r+   r   r   Ú	stripCodeh   s   "ÿz.NBNSProtocol.queryIPForName.<locals>.stripCode)r3   r4   r   ÚprepareNetNameQueryr.   r   r8   Ú
addErrbackÚerrbackÚaddCallbackr9   r    )r   r*   r&   r;   r'   r#   Úd2rF   r   rE   r   ÚqueryIPForNameM   s   
ü

zNBNSProtocol.queryIPForNamec                 C   s   t  | ¡ d S r   )r   ÚstopProtocol©r   r   r   r   rM   p   s   zNBNSProtocol.stopProtocolc                    sR   t   ¡ ‰ t‡ fdd„ˆj ¡ ƒ}‡fdd„}t||ƒ ˆjr't dˆj¡ d S d S )Nc                    s   |d ˆ k S r=   r   )r'   Úinfo)Únowr   r   r@   x   rB   z1NBNSProtocol.cleanupPendingTrns.<locals>.<lambda>c                    s8   | \}\}}}ˆ j |= z
| t|ƒ¡ W d S    Y d S r   )r   rI   r   )Úitemr'   Úexpiry_timer:   r+   rN   r   r   Úexpire_item{   s
   z4NBNSProtocol.cleanupPendingTrns.<locals>.expire_itemr   )	r9   rD   r   Ú	iteritemsrC   r   r   r   r   )r   ÚexpiredrS   r   )rP   r   r   r   s   s   
ÿzNBNSProtocol.cleanupPendingTrnsN)Tr   )r/   r0   r1   )r0   r1   )r   r	   r
   ÚloggingÚ	getLoggerr6   r   r,   r.   r<   rL   rM   r   r   r   r   r   r      s    



#r   )ÚosrV   r3   r   r9   Útwisted.internetr   r   Útwisted.internet.protocolr   Úbaser   Ú	Exceptionr   r   r   r   r   r   Ú<module>   s   (