+
    DfjhC                     2   R t ^ RIt^ RIt^ RIHt ^ RIHtHtHtH	t	H
t
HtHtHt ^ RIHt ^ RIHt ^ RIHt ^ RIHt ^ RIHt ^ R	IHt ^ R
IHtHtHtHt ^ RIH t  ^t!R t"Rt#R t$R t%R t& ! R R4      t'R t(]! ]4       ! R R4      4       t) ! R R4      t*R# )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)nativeStringc                0    \         P                  ! RV 4      # )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   &6/usr/lib/python3/dist-packages/twisted/pair/testing.py_Hr      s     ;;tQ       c                @    W,           \        V4      ,           V,           # )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    & 9r(|#g--r   c                :   R\        ^\        V4      ,           4      ,           R,           \        ^ 4      ,           \        P                  ! \        P                  \        V 4      4      ,           \        P                  ! \        P                  \        V4      4      ,           p\        \        P                  ! RV4      4      pV^,	          pVR,          V,           pVR,          pVR,          \        P                  ! RV4      ,           VR,          ,           pW2,           # )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      @z!10Hi  :N
   Nz!H:   NN)
r   lensocket	inet_ptonAF_INETr   sumr   unpackr   )r!   r"   r$   ipHeaderchecksumStep1carrychecksumStep2checksumStep3s   &&&     r   _ipr4   D   s    &	 R#g,
		 
 &	& Q%	 

6>><+<
=		> 

6>><+<
=	> " fh78MRE"V+u4M!F*M
 }v{{4??(3-OHr   c                    \        V 4      \        V4      ,           \        \        V4      ^,           4      ,           \        ^ 4      ,           pW2,           # )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$   	udpHeaders   &&& r   _udpr7   v   sM    & 	3
S'	 S\A
		 Q%	  r   c                      a  ] tR t^t o RtRt]! ]R4      t]	! ]
R4      t]! ]R4      t]tRtR t]R 4       t]R	 4       tR
 tR tR tRtV tR# )Tunnelz
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                    Wn         W n        RV n        RV n        RV n        \        4       V n        \        4       V n        \        4       V n        R# )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)selfr;   r<   fileModes   &&&&r   __init__Tunnel.__init__   sC      #!	' 7#gr   c                Z    V P                   V P                  P                  ,          '       * # )z`
If the file descriptor for this tunnel is open in blocking mode,
C{True}.  C{False} otherwise.
)r<   r;   
O_NONBLOCKrC   s   &r   blockingTunnel.blocking   s      NNT[[%;%;;<<r   c                b    \        V P                  V P                  P                  ,          4      # )zb
If the file descriptor for this tunnel is marked as close-on-exec,
C{True}.  C{False} otherwise.
)boolr<   r;   	O_CLOEXECrI   s   &r   closeOnExecTunnel.closeOnExec   s"     DNNT[[%:%::;;r   c                    V P                   \        P                  P                  ,          '       d   \	        RR\
        VR7      pV P                  P                  V4       R# )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}
r    Ns         s   )r=   r   IFF_TAPvaluer%   _IPv4r@   appendrC   datagrams   &&r   addToReadBufferTunnel.addToReadBuffer   sF     ??[006666 [5(H 	x(r   c                P   V P                   '       dn   V P                  \        P                  P                  ,          '       d   RpMR\
        ,          pV^,          pW P                   P                  4       RV ,           # V P                  '       d   \        4       hV P                  h)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       N)
r@   r=   r   	IFF_NO_PIrS   _PI_SIZEpopleftrJ   NotImplementedErrornonBlockingExceptionStyle)rC   limitheaders   && r   readTunnel.read   s}    ( ???!6!6!<!<<<
 !8+
OO335fu===]]]%''000r   c                   V P                   '       d+   V P                   P                  4        \        \        R4      h\	        V4      V P
                  8  d   \        \        R4      hV P                  P                  V4       \	        V4      # )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)	rB   r^   OSErrorr   r)   SEND_BUFFER_SIZEr   rA   rU   rV   s   &&r   writeTunnel.write  sn     '')%!:;;x=4000'#>??)8}r   )r?   r<   rB   r@   r>   r;   r=   rA   N)__name__
__module____qualname____firstlineno____doc___DEVICE_NAMEIOErrorr   EAGAIN_STYLErf   r
   EWOULDBLOCK_STYLEr   EINTR_STYLEr`   rg   rE   propertyrJ   rO   rX   rc   rh   __static_attributes____classdictcell____classdict__s   @r   r9   r9      s      #L 6#EFL-DE %!<=K ,&. = = < <)"!1F r   r9   c                0   a  \        S 4      V 3R l4       pV# )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                 r   < SP                   V P                  9  d   \        \        R 4      hS! V .VO5/ VB # )zOperation not permitted)rj   permissionsrf   r	   )rC   argskwargsoriginals   &*,r   permissionChecker&_privileged.<locals>.permissionChecker+  s:    D$4$44%!:;;.t.v..r   r   )r~   r   s   f r   _privilegedr     s#     8_/ /
 r   c                      a  ] tR tRt o RtRt^t^t^tR t	R t
R t]RR l4       tR	 tR
 tR t]R 4       tR tR tRtV tR# )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    c                4    / V n         / V n        R R0V n        R# )openioctlN_devices
_openFilesr{   rI   s   &r   rE   MemoryIOSystem.__init__G  s    "G,r   c                D    V P                   VP                  4       ,          # )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)rC   ports   &&r   	getTunnelMemoryIOSystem.getTunnelL  s     t{{}--r   c                "    W P                   V&   R# )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   )rC   r?   clss   &&&r   registerSpecialDevice$MemoryIOSystem.registerSpecialDeviceY  s     "dr   Nc                    WP                   9   dO   V P                  pV ;P                  ^,          un        V P                   V,          ! WV4      V P                  V&   V# \        \        R4      h)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}
zFunction not implemented)r   _counterr   rf   r   )rC   r?   flagsmodefds   &&&& r   r   MemoryIOSystem.openf  sV    0 == BMMQM"&--"5d4"HDOOBIf899r   c                     V P                   V,          P                  V4      #   \         d    \        \        R4      hi ; i)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   rc   KeyErrorrf   r   )rC   r   ra   s   &&&r   rc   MemoryIOSystem.read  s>    	8??2&++E22 	8%!677	8	   !$ A c                     V P                   V,          P                  V4      #   \         d    \        \        R4      hi ; i)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   rh   r   rf   r   )rC   r   datas   &&&r   rh   MemoryIOSystem.write  s>    	8??2&,,T22 	8%!677	8r   c                `     V P                   V R#   \         d    \        \        R4      hi ; i)zj
Discard the in-memory buffer and other in-memory state for the given
file descriptor.

@see: L{os.close}
r   N)r   r   rf   r   )rC   r   s   &&r   closeMemoryIOSystem.close  s0    	8# 	8%!677	8s    -c                    V P                   V,          pT\        8w  d   \        \
        R4      h\        P                  ! R\        3,          T4      w  rVYdn	        YTn
        TR\        ^,
           R,           Tn        \        P                  ! R\        3,          TP                  T4      #   \         d    \        \        R4      hi ; i)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%dsHNs   123)r   r   rf   r   r   r   r   r.   r   r=   r>   r?   r   )rC   r   requestr|   tunnelr?   r   s   &&&&   r   r   MemoryIOSystem.ioctl  s    	8__R(F j &"ABB]]6YL#8$?
 #?Y]+f4{{6YL0&++tDD  	8%!677	8s   B+ +Cc           
         RpRp\        VV^ ,          \        WB^,          VR7      R7      p\        V P                  P	                  4       4      pV^ ,          P                  V4       W43# )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$   )r4   r7   listr   valuesrX   )rC   rW   addresssrcIPsrcPort
serialized	openFiless   &&&    r   sendUDPMemoryIOSystem.sendUDP  sd    " 
W!*hG

 //12	!$$Z0r   c                    \        W4      # )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)rC   r   hostr   s   &&&&r   
receiveUDPMemoryIOSystem.receiveUDP  s    & &&r   r   N)rj   rk   rl   rm   rn   r   O_RDWRrH   rN   rE   r   r   r   r   rc   rh   r   r   r   r   ru   rv   rw   s   @r   r   r   4  sw     	 HFJI-
." : :<
8
8
8 E E, >' 'r   r   c                   0   a  ] tR tRt o RtR tR tRtV tR# )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                    Wn         W n        R # r   )_system_fileno)rC   r;   r   s   &&&r   rE   _FakePort.__init__  s    r   c                  a
a V P                   P                  V P                  ,          P                  P	                  4       p. o
\        4       pV
3R lpWCn        \        4       pVP                  RV4       \        4       oSP                  ^V4       V P                   P                  V P                  ,          P                  pV\        P                  P                  ,          '       d*   \        4       pVP                  RS4       VP                  pMV3R lpV\        P                  P                  ,          '       * p	V	'       d
   V\         R pV! V4       S
^ ,          RV # )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                 *   < SP                  V 4       R # r   )rU   )rW   r   	datagramss   &&r   capture_FakePort.recv.<locals>.capture  s    X&r   i90  r   c                 .   < SP                  V R R R R 4      # r   )datagramReceived)r   ips   &r   <lambda> _FakePort.recv.<locals>.<lambda>   s    B,?,?dD$-r   N)r   r   r   rA   r^   r   r   r   addProtor   r=   r   rR   rS   r   r\   r]   )rC   nbytesr   receiverr   udpr   etherr   	dataHasPIr   r   s   &&        @@r   recv_FakePort.recv  s    ||&&t||4@@HHJ	#%	' %,!UH%\
B||&&t||4??+%%++++$&ENN5"%$55   5 5 ; ;;<		?D|GV$$r   )r   r   N)	rj   rk   rl   rm   rn   rE   r   ru   rv   rw   s   @r   r   r     s     
,% ,%r   r   )+rn   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   r]   r   rT   r%   r4   r7   r9   r   r   r    r   r   <module>r      s       S S S  & 6 2 & . W W . 
  	.,/d<H HV*  !}' }' "}'@6% 6%r   