ó
    Ö›‘hhC  ã                   ó0  • S r SSKrSSKrSSKJr  SSKJrJrJrJ	r	J
r
JrJrJr  SSKJr  SSKJr  SSKJr  SSKJr  SS	KJr  SS
KJr  SSKJrJrJrJr  SSKJ r   Sr!S r"Sr#S r$S r%S r& " S S5      r'S r(\" \5       " S S5      5       r) " S S5      r*g)zD
Tools for automated testing of L{twisted.pair}-based applications.
é    N)Údeque)ÚEAGAINÚEBADFÚEINTRÚEINVALÚENOBUFSÚENOSYSÚEPERMÚEWOULDBLOCK©Úwraps)Úimplementer)ÚDatagramProtocol)ÚEthernetProtocol)Ú
IPProtocol)ÚRawUDPProtocol)Ú	_IFNAMSIZÚ
_TUNSETIFFÚTunnelFlagsÚ_IInputOutputSystem)ÚnativeStringé   c                 ó0   • [         R                  " SU 5      $ )zÒ
Pack an integer into a network-order two-byte string.

@param n: The integer to pack.  Only values that fit into 16 bits are
    supported.

@return: The packed representation of the integer.
@rtype: L{bytes}
z>H)ÚstructÚpack)Úns    ÚXC:\Users\psant\Downloads\Noiseback\school\venv\Lib\site-packages\twisted/pair/testing.pyÚ_Hr      s   € ô �;Š;�t˜QÓÐó    é   c                 ó(   • X-   [        U5      -   U-   $ )a¨  
Construct an ethernet frame.

@param src: The source ethernet address, encoded.
@type src: L{bytes}

@param dst: The destination ethernet address, encoded.
@type dst: L{bytes}

@param protocol: The protocol number of the payload of this datagram.
@type protocol: L{int}

@param payload: The content of the ethernet frame (such as an IP datagram).
@type payload: L{bytes}

@return: The full ethernet frame.
@rtype: L{bytes}
)r   ©ÚsrcÚdstÚprotocolÚpayloads       r   Ú	_ethernetr'   .   s   € ð& ‰9”r˜(“|Ñ# gÑ-Ð-r   c                 óÂ  • S[        S[        U5      -   5      -   S-   [        S5      -   [        R                  " [        R                  [        U 5      5      -   [        R                  " [        R                  [        U5      5      -   n[        [        R                  " SU5      5      nUS-	  nUS-  U-   nUS-  nUSS	 [        R                  " S
U5      -   USS -   nX2-   $ )a   
Construct an IP datagram with the given source, destination, and
application payload.

@param src: The source IPv4 address as a dotted-quad string.
@type src: L{bytes}

@param dst: The destination IPv4 address as a dotted-quad string.
@type dst: L{bytes}

@param payload: The content of the IP datagram (such as a UDP datagram).
@type payload: L{bytes}

@return: An IP datagram header and payload.
@rtype: L{bytes}
s   E é   s      @r   z!10Hé   iÿÿ  Né
   z!Hé   )
r   ÚlenÚsocketÚ	inet_ptonÚAF_INETr   Úsumr   Úunpackr   )r#   r$   r&   ÚipHeaderÚchecksumStep1ÚcarryÚchecksumStep2ÚchecksumStep3s           r   Ú_ipr8   D   sç   € ð&	ô ˆR”#�g“,ÑÓ
ñ		 ð
 &ñ	&ô ˆQ‹%ñ	ô ×
Ò
œ6Ÿ>™>¬<¸Ó+<Ó
=ñ		>ô ×
Ò
œ6Ÿ>™>¬<¸Ó+<Ó
=ñ	>ð ô" œŸš f¨hÓ7Ó8€Mà˜RÑ€Eà" VÑ+¨uÑ4€Mà! FÑ*€Mð
 ˜˜ˆ}œvŸ{š{¨4°Ó?Ñ?À(È2È3À-ÑO€HàÑÐr   c                 ó€   • [        U 5      [        U5      -   [        [        U5      S-   5      -   [        S5      -   nX2-   $ )aR  
Construct a UDP datagram with the given source, destination, and
application payload.

@param src: The source port number.
@type src: L{int}

@param dst: The destination port number.
@type dst: L{int}

@param payload: The content of the UDP datagram.
@type payload: L{bytes}

@return: A UDP datagram header and payload.
@rtype: L{bytes}
é   r   )r   r-   )r#   r$   r&   Ú	udpHeaders       r   Ú_udpr<   v   sM   € ô& 	ˆ3‹ä
ˆS‹'ñ	ô ŒS�‹\˜AÑÓ
ñ		ô ˆQ‹%ñ	ð ð ÑÐr   c                   ó’   • \ rS rSrSrSr\" \S5      r\	" \
S5      r\" \S5      r\rSrS r\S	 5       r\S
 5       rS rS rS rSrg)ÚTunnelé”   zÔ
An in-memory implementation of a tun or tap device.

@cvar _DEVICE_NAME: A string representing the conventional filesystem entry
    for the tunnel factory character special device.
@type _DEVICE_NAME: C{bytes}
s   /dev/net/tunz Resource temporarily unavailablezOperation would blockzInterrupted function calli   c                 ó    • Xl         X l        SU l        SU l        SU l        [        5       U l        [        5       U l        [        5       U l        g)zÖ
@param system: An L{_IInputOutputSystem} provider to use to perform I/O.

@param openFlags: Any flags to apply when opening the tunnel device.
    See C{os.O_*}.

@type openFlags: L{int}

@param fileMode: ignored
N)	ÚsystemÚ	openFlagsÚ
tunnelModeÚrequestedNameÚnamer   Ú
readBufferÚwriteBufferÚpendingSignals)ÚselfrA   rB   ÚfileModes       r   Ú__init__ÚTunnel.__init__¬   sC   € ð Œð #ŒØˆŒØ!ˆÔØˆŒ	Ü›'ˆŒÜ ›7ˆÔÜ#›gˆÕr   c                 óR   • U R                   U R                  R                  -  (       + $ )z`
If the file descriptor for this tunnel is open in blocking mode,
C{True}.  C{False} otherwise.
)rB   rA   Ú
O_NONBLOCK©rI   s    r   ÚblockingÚTunnel.blockingÃ   s    € ð —N‘N T§[¡[×%;Ñ%;Ñ;Ô<Ð<r   c                 óZ   • [        U R                  U R                  R                  -  5      $ )zb
If the file descriptor for this tunnel is marked as close-on-exec,
C{True}.  C{False} otherwise.
)ÚboolrB   rA   Ú	O_CLOEXECrO   s    r   ÚcloseOnExecÚTunnel.closeOnExecË   s"   € ô �D—N‘N T§[¡[×%:Ñ%:Ñ:Ó;Ð;r   c                 ó²   • U R                   [        R                  R                  -  (       a  [	        SS[
        US9nU R                  R                  U5        g)a  
Deliver a datagram to this tunnel's read buffer.  This makes it
available to be read later using the C{read} method.

@param datagram: The IPv4 datagram to deliver.  If the mode of this
    tunnel is TAP then ethernet framing will be added automatically.
@type datagram: L{bytes}
s         s   ÿÿÿÿÿÿr"   N)rC   r   ÚIFF_TAPÚvaluer'   Ú_IPv4rF   Úappend©rI   Údatagrams     r   ÚaddToReadBufferÚTunnel.addToReadBufferÓ   sC   € ð �?‰?œ[×0Ñ0×6Ñ6×6Ü Ø [¼5È(ñˆHð 	�‰×Ñ˜xÕ(r   c                 ó*  • U R                   (       a\  U R                  [        R                  R                  -  (       a  SnOS[
        -  nUS-  nX R                   R                  5       SU -   $ U R                  (       a
  [        5       eU R                  e)aª  
Read a datagram out of this tunnel.

@param limit: The maximum number of bytes from the datagram to return.
    If the next datagram is larger than this, extra bytes are dropped
    and lost forever.
@type limit: L{int}

@raise OSError: Any of the usual I/O problems can result in this
    exception being raised with some particular error number set.

@raise IOError: Any of the usual I/O problems can result in this
    exception being raised with some particular error number set.

@return: The datagram which was read from the tunnel.  If the tunnel
    mode does not include L{TunnelFlags.IFF_NO_PI} then the datagram is
    prefixed with a 4 byte PI header.
@rtype: L{bytes}
r   ó    r   N)
rF   rC   r   Ú	IFF_NO_PIrY   Ú_PI_SIZEÚpopleftrP   ÚNotImplementedErrorÚnonBlockingExceptionStyle)rI   ÚlimitÚheaders      r   ÚreadÚTunnel.readä   sv   € ð( �?�?Ø�‰¤×!6Ñ!6×!<Ñ!<×<Ø‘ð
 !¤8Ñ+�Ø˜‘
�ØŸO™O×3Ñ3Ó5°f°uÐ=Ñ=Ð=Ø�]�]Ü%Ó'Ð'à×0Ñ0Ð0r   c                 ó  • U R                   (       a*  U R                   R                  5         [        [        S5      e[	        U5      U R
                  :”  a  [        [        S5      eU R                  R                  U5        [	        U5      $ )a;  
Write a datagram into this tunnel.

@param datagram: The datagram to write.
@type datagram: L{bytes}

@raise IOError: Any of the usual I/O problems can result in this
    exception being raised with some particular error number set.

@return: The number of bytes of the datagram which were written.
@rtype: L{int}
zInterrupted system callzNo buffer space available)	rH   rd   ÚOSErrorr   r-   ÚSEND_BUFFER_SIZEr   rG   r[   r\   s     r   ÚwriteÚTunnel.write  sk   € ð ××Ø×Ñ×'Ñ'Ô)Üœ%Ð!:Ó;Ð;äˆx‹=˜4×0Ñ0Ó0Üœ'Ð#>Ó?Ð?à×Ñ×Ñ Ô)Ü�8‹}Ðr   )rE   rB   rH   rF   rD   rA   rC   rG   N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú_DEVICE_NAMEÚIOErrorr   ÚEAGAIN_STYLErl   r   ÚEWOULDBLOCK_STYLEr   ÚEINTR_STYLErf   rm   rK   ÚpropertyrP   rU   r^   ri   rn   Ú__static_attributes__© r   r   r>   r>   ”   sƒ   † ñð #€Lñ ˜6Ð#EÓF€LÙ Ð-DÓEÐñ ˜%Ð!<Ó=€Kà ,ÐàÐò&ð. ñ=ó ð=ð ñ<ó ð<ò)ò"!1õFr   r>   c                 ó0   ^ • [        T 5      U 4S j5       nU$ )a`  
Wrap a L{MemoryIOSystem} method with permission-checking logic.  The
returned function will check C{self.permissions} and raise L{IOError} with
L{errno.EPERM} if the function name is not listed as an available
permission.

@param original: The L{MemoryIOSystem} instance to wrap.

@return: A wrapper around C{original} that applies permission checks.
c                 óp   >• TR                   U R                  ;  a  [        [        S5      eT" U /UQ70 UD6$ )NzOperation not permitted)rp   Úpermissionsrl   r
   )rI   ÚargsÚkwargsÚoriginals      €r   ÚpermissionCheckerÚ&_privileged.<locals>.permissionChecker+  s:   ø€ à×Ñ D×$4Ñ$4Ó4Üœ%Ð!:Ó;Ð;Ù˜Ð.˜tÒ. vÑ.Ð.r   r   )r‚   rƒ   s   ` r   Ú_privilegedr…     s#   ø€ ô ˆ8ƒ_ô/ó ð/ð
 Ðr   c                   ó|   • \ rS rSrSrSrSrSrSrS r	S r
S	 r\SS j5       rS rS rS r\S 5       rS rS rSrg
)ÚMemoryIOSystemi4  zÛ
An in-memory implementation of basic I/O primitives, useful in the context
of unit testing as a drop-in replacement for parts of the C{os} module.

@ivar _devices:
@ivar _openFiles:
@ivar permissions:

@ivar _counter:
i    é   é   r   c                 ó2   • 0 U l         0 U l        SS1U l        g )NÚopenÚioctl©Ú_devicesÚ
_openFilesr   rO   s    r   rK   ÚMemoryIOSystem.__init__G  s   € ØˆŒØˆŒØ" GÐ,ˆÕr   c                 ó<   • U R                   UR                  5          $ )a   
Get the L{Tunnel} object associated with the given L{TuntapPort}.

@param port: A L{TuntapPort} previously initialized using this
    L{MemoryIOSystem}.

@return: The tunnel object created by a prior use of C{open} on this
    object on the tunnel special device file.
@rtype: L{Tunnel}
)r�   Úfileno)rI   Úports     r   Ú	getTunnelÚMemoryIOSystem.getTunnelL  s   € ð �‰˜tŸ{™{›}Ñ-Ð-r   c                 ó    • X R                   U'   g)zù
Specify a class which will be used to handle I/O to a device of a
particular name.

@param name: The filesystem path name of the device.
@type name: L{bytes}

@param cls: A class (like L{Tunnel}) to instantiated whenever this
    device is opened.
N)rŽ   )rI   rE   Úclss      r   ÚregisterSpecialDeviceÚ$MemoryIOSystem.registerSpecialDeviceY  s   € ð "�‰�dÒr   Nc                 óÌ   • XR                   ;   aF  U R                  nU =R                  S-  sl        U R                   U   " XU5      U R                  U'   U$ [        [        S5      e)a~  
A replacement for C{os.open}.  This initializes state in this
L{MemoryIOSystem} which will be reflected in the behavior of the other
file descriptor-related methods (eg L{MemoryIOSystem.read},
L{MemoryIOSystem.write}, etc).

@param name: A string giving the name of the file to open.
@type name: C{bytes}

@param flags: The flags with which to open the file.
@type flags: C{int}

@param mode: The mode with which to open the file.
@type mode: C{int}

@raise OSError: With C{ENOSYS} if the file is not a recognized special
    device file.

@return: A file descriptor associated with the newly opened file
    description.
@rtype: L{int}
rˆ   zFunction not implemented)rŽ   Ú_counterr�   rl   r	   )rI   rE   ÚflagsÚmodeÚfds        r   r‹   ÚMemoryIOSystem.openf  sV   € ð0 —=‘=Ó Ø—‘ˆBØ�MŠM˜QÑ�MØ"&§-¡-°Ò"5°dÀ4Ó"HˆD�O‰O˜BÑØˆIÜ”fÐ8Ó9Ð9r   c                 ó|   •  U R                   U   R                  U5      $ ! [         a    [        [        S5      ef = f)z„
Try to read some bytes out of one of the in-memory buffers which may
previously have been populated by C{write}.

@see: L{os.read}
úBad file descriptor)r�   ri   ÚKeyErrorrl   r   )rI   rž   rg   s      r   ri   ÚMemoryIOSystem.read…  s>   € ð	8Ø—?‘? 2Ñ&×+Ñ+¨EÓ2Ð2øÜó 	8Üœ%Ð!6Ó7Ð7ð	8úó   ‚   ;c                 ó|   •  U R                   U   R                  U5      $ ! [         a    [        [        S5      ef = f)zr
Try to add some bytes to one of the in-memory buffers to be accessed by
a later C{read} call.

@see: L{os.write}
r¡   )r�   rn   r¢   rl   r   )rI   rž   Údatas      r   rn   ÚMemoryIOSystem.write‘  s>   € ð	8Ø—?‘? 2Ñ&×,Ñ,¨TÓ2Ð2øÜó 	8Üœ%Ð!6Ó7Ð7ð	8úr¤   c                 ó\   •  U R                   U	 g! [         a    [        [        S5      ef = f)zj
Discard the in-memory buffer and other in-memory state for the given
file descriptor.

@see: L{os.close}
r¡   N)r�   r¢   rl   r   )rI   rž   s     r   ÚcloseÚMemoryIOSystem.close�  s0   € ð	8Ø—‘ Ñ#øÜó 	8Üœ%Ð!6Ó7Ð7ð	8ús   ‚ �+c                 óh  •  U R                   U   nU[        :w  a  [        [
        S5      e[        R                  " S[        4-  U5      u  pVXdl	        XTl
        US[        S-
   S-   Ul        [        R                  " S[        4-  UR                  U5      $ ! [         a    [        [        S5      ef = f)zo
Perform some configuration change to the in-memory state for the given
file descriptor.

@see: L{fcntl.ioctl}
r¡   zRequest or args is not valid.z%dsHNé   s   123)r�   r¢   rl   r   r   r   r   r2   r   rC   rD   rE   r   )rI   rž   Úrequestr€   ÚtunnelrE   r�   s          r   rŒ   ÚMemoryIOSystem.ioctl©  s¦   € ð	8Ø—_‘_ RÑ(ˆFð ”jÓ Üœ&Ð"AÓBÐBä—]’] 6¬Y¨LÑ#8¸$Ó?‰
ˆØ ÔØ#ÔØ˜?œY¨™]Ð+¨fÑ4ˆŒä�{Š{˜6¤Y LÑ0°&·+±+¸tÓDÐDøô ó 	8Üœ%Ð!6Ó7Ð7ð	8ús   ‚B ÂB1c           
      ó°   • SnSn[        UUS   [        XBS   US9S9n[        U R                  R	                  5       5      nUS   R                  U5        X44$ )a  
Write an ethernet frame containing an ip datagram containing a udp
datagram containing the given payload, addressed to the given address,
to a tunnel device previously opened on this I/O system.

@param datagram: A UDP datagram payload to send.
@type datagram: L{bytes}

@param address: The destination to which to send the datagram.
@type address: L{tuple} of (L{bytes}, L{int})

@return: A two-tuple giving the address from which gives the address
    from which the datagram was sent.
@rtype: L{tuple} of (L{bytes}, L{int})
z10.1.2.3iaS  r   rˆ   )r#   r$   r&   )r8   r<   Úlistr�   Úvaluesr^   )rI   r]   ÚaddressÚsrcIPÚsrcPortÚ
serializedÚ	openFiless          r   ÚsendUDPÚMemoryIOSystem.sendUDPÀ  sd   € ð" ˆØˆäØØ˜‘
Ü˜W°!©*¸hÑGñ
ˆ
ô ˜Ÿ™×/Ñ/Ó1Ó2ˆ	Ø�!‰×$Ñ$ ZÔ0àÐÐr   c                 ó   • [        X5      $ )aù  
Get a socket-like object which can be used to receive a datagram sent
from the given address.

@param fileno: A file descriptor representing a tunnel device which the
    datagram will be received via.
@type fileno: L{int}

@param host: The IPv4 address to which the datagram was sent.
@type host: L{bytes}

@param port: The UDP port number to which the datagram was sent.
    received.
@type port: L{int}

@return: A L{socket.socket}-like object which can be used to receive
    the specified datagram.
)Ú	_FakePort)rI   r’   Úhostr“   s       r   Ú
receiveUDPÚMemoryIOSystem.receiveUDPß  s   € ô& ˜Ó&Ð&r   r�   ©N)rp   rq   rr   rs   rt   r›   ÚO_RDWRrN   rT   rK   r”   r˜   r…   r‹   ri   rn   r©   rŒ   r¸   r½   r{   r|   r   r   r‡   r‡   4  so   † ñ	ð €Hà€FØ€JØ€Iò-ò
.ò"ð ó:ó ð:ò<
8ò
8ò
8ð ñEó ðEò, õ>'r   r‡   c                   ó$   • \ rS rSrSrS rS rSrg)r»   iõ  z€
A socket-like object which can be used to read UDP datagrams from
tunnel-like file descriptors managed by a L{MemoryIOSystem}.
c                 ó   • Xl         X l        g r¿   )Ú_systemÚ_fileno)rI   rA   r’   s      r   rK   Ú_FakePort.__init__û  s   € ØŒØ�r   c                 óœ  ^
^• U R                   R                  U R                     R                  R	                  5       n/ m
[        5       nU
4S jnXCl        [        5       nUR                  SU5        [        5       mTR                  SU5        U R                   R                  U R                     R                  nU[        R                  R                  -  (       a)  [        5       nUR                  ST5        UR                  nOU4S jnU[        R                  R                  -  (       + n	U	(       a	  U[         S nU" U5        T
S   SU $ )a'  
Receive a datagram sent to this port using the L{MemoryIOSystem} which
created this object.

This behaves like L{socket.socket.recv} but the data being I{sent} and
I{received} only passes through various memory buffers managed by this
object and L{MemoryIOSystem}.

@see: L{socket.socket.recv}
c                 ó(   >• TR                  U 5        g r¿   )r[   )r]   r³   Ú	datagramss     €r   ÚcaptureÚ_FakePort.recv.<locals>.capture  s   ø€ Ø×Ñ˜XÕ&r   i90  é   r    c                 ó.   >• TR                  U S S S S 5      $ r¿   )ÚdatagramReceived)r¦   Úips    €r   Ú<lambda>Ú _FakePort.recv.<locals>.<lambda>   s   ø€ ¨B×,?Ñ,?Ø�d˜D $¨ô-r   Nr   )rÃ   r�   rÄ   rG   rd   r   rÍ   r   ÚaddProtor   rC   r   rX   rY   r   rb   rc   )rI   Únbytesr¦   ÚreceiverrÉ   Úudpr�   ÚetherrÍ   Ú	dataHasPIrÈ   rÎ   s             @@r   ÚrecvÚ_FakePort.recvÿ  s  ù€ ð �|‰|×&Ñ& t§|¡|Ñ4×@Ñ@×HÑHÓJˆàˆ	Ü#Ó%ˆõ	'ð %,Ô!äÓˆØ�‰�U˜HÔ%ä‹\ˆØ
�‰�B˜Ôà�|‰|×&Ñ& t§|¡|Ñ4×?Ñ?ˆØ”+×%Ñ%×+Ñ+×+Ü$Ó&ˆEØ�N‰N˜5 "Ô%Ø$×5Ñ5Ñô Ðð ¤× 5Ñ 5× ;Ñ ;Ñ;Ô<ˆ	æàœ˜	�?ˆDá˜ÔØ˜‰|˜G˜VÐ$Ð$r   )rÄ   rÃ   N)rp   rq   rr   rs   rt   rK   r×   r{   r|   r   r   r»   r»   õ  s   † ñò
õ,%r   r»   )+rt   r.   r   Úcollectionsr   Úerrnor   r   r   r   r   r	   r
   r   Ú	functoolsr   Úzope.interfacer   Útwisted.internet.protocolr   Útwisted.pair.ethernetr   Útwisted.pair.ipr   Útwisted.pair.rawudpr   Útwisted.pair.tuntapr   r   r   r   Útwisted.python.compatr   rc   r   rZ   r'   r8   r<   r>   r…   r‡   r»   r|   r   r   Ú<module>rã      s›   ðñó Û Ý ß S× SÓ SÝ å &å 6Ý 2Ý &Ý .ß WÓ WÝ .ð €ò
 ð 	€ò.ò,/òd÷<Hñ HòVñ* Ð Ó!÷}'ð }'ó "ð}'÷@6%ò 6%r   