
    \d1                        d Z ddlZ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 ddl	m
Z
 ddlmZmZmZ ddlmZmZ ddlmZ ddlmZmZmZmZmZ dd	lmZmZ dd
lmZ ddlm Z  ddl!m"Z" ddl#m$Z$m%Z% g dZ&dZ' ej(                    dk    sD ej(                    )                    d          s" ej(                    )                    d          rdZ*dZ+ndZ*dZ+dZ, G d de          Z- eej.                   G d de%e$                      Z/ G d d edd                    Z0 G d d e          Z1 G d! d"          Z2 eej3                   G d# d$ej4                              Z5dS )%zc
Support for Linux ethernet and IP tunnel devices.

@see: U{https://en.wikipedia.org/wiki/TUN/TAP}
    N)
namedtuple)Tuple)	Attribute	Interfaceimplementer)FlagConstantFlags)Version)abstractdefererror
interfacestask)ethernetraw)log)
deprecated)fullyQualifiedName)FancyEqMixinFancyStrMixin)TunnelFlagsTunnelAddress
TuntapPort   pariscppcsparcl   T  iT@iT@l   T  s   /dev/net/tunc                      e Zd ZdZ ed          Z ed          Z ed          Z ed          Z ed          Z	 ed          Z
 ed          Z ed	          Z ed
          Z ed          Z ed          Z ed          ZdS )r   a~  
    L{TunnelFlags} defines more flags which are used to configure the behavior
    of a tunnel device.

    @cvar IFF_TUN: This indicates a I{tun}-type device.  This type of tunnel
        carries IP datagrams.  This flag is mutually exclusive with C{IFF_TAP}.

    @cvar IFF_TAP: This indicates a I{tap}-type device.  This type of tunnel
        carries ethernet frames.  This flag is mutually exclusive with C{IFF_TUN}.

    @cvar IFF_NO_PI: This indicates the I{protocol information} header will
        B{not} be included in data read from the tunnel.

    @see: U{https://www.kernel.org/doc/Documentation/networking/tuntap.txt}
          r       @         i   i       i @  i   N)__name__
__module____qualname____doc__r   IFF_TUNIFF_TAP
TUN_FASYNCTUN_NOCHECKSUM	TUN_NO_PITUN_ONE_QUEUETUN_PERSISTTUN_VNET_HDR	IFF_NO_PIIFF_ONE_QUEUEIFF_VNET_HDRIFF_TUN_EXCL     3lib/python3.11/site-packages/twisted/pair/tuntap.pyr   r   6   s           l6""Gl6""Gf%%J!\&))NV$$I L((M,v&&K<''LV$$I L((M<''L<''LLLr7   r   c                   F    e Zd ZdZdZdd fdfZed             Zd Zd Z	d	S )
r   zU
    A L{TunnelAddress} represents the tunnel to which a L{TuntapPort} is bound.
    )
_typeValuenametypec                     | j         S N)r;   )flags    r8   <lambda>zTunnelAddress.<lambda>^   s    DI r7   r;   c                     | j         j        S )z
        Return the integer value of the C{type} attribute.  Used to produce
        correct results in the equality implementation.
        )r<   valueselfs    r8   r:   zTunnelAddress._typeValue`   s     yr7   c                 "    || _         || _        dS )z
        @param type: Either L{TunnelFlags.IFF_TUN} or L{TunnelFlags.IFF_TAP},
            representing the type of this tunnel.

        @param name: The system name of the tunnel.
        @type name: L{bytes}
        N)r<   r;   )rD   r<   r;   s      r8   __init__zTunnelAddress.__init__i   s     				r7   c                 X    t          j        dt          d           d| j        f|         S )zS
        Deprecated accessor for the tunnel name.  Use attributes instead.
        zUTunnelAddress.__getitem__ is deprecated since Twisted 14.0.0  Use attributes instead.r    )category
stacklevelTUNTAP)warningswarnDeprecationWarningr;   )rD   indexs     r8   __getitem__zTunnelAddress.__getitem__t   s<     	&'		
 	
 	
 	
 $)$U++r7   N)
r&   r'   r(   r)   compareAttributesshowAttributespropertyr:   rF   rO   r6   r7   r8   r   r   W   sp          /556?N  X	 	 	
, 
, 
, 
, 
,r7   r   c                       e Zd ZdZdS )_TunnelDescriptionz
    Describe an existing tunnel.

    @ivar fileno: the file descriptor associated with the tunnel
    @type fileno: L{int}

    @ivar name: the name of the tunnel
    @type name: L{bytes}
    N)r&   r'   r(   r)   r6   r7   r8   rT   rT      s           r7   rT   zfileno namec                       e Zd ZdZ ed          Z ed          Z ed          ZddZddZ	d	 Z
d
 Zd Zd Zd ZdS )_IInputOutputSystemz
    An interface for performing some basic kinds of I/O (particularly that I/O
    which might be useful for L{twisted.pair.tuntap}-using code).
    z@see: L{os.O_RDWR}z@see: L{os.O_NONBLOCK}z@see: L{os.O_CLOEXEC}  c                     dS )z"
        @see: L{os.open}
        Nr6   )filenamer?   modes      r8   openz_IInputOutputSystem.open         r7   Nc                     dS )z&
        @see: L{fcntl.ioctl}
        Nr6   )fdoptargmutate_flags       r8   ioctlz_IInputOutputSystem.ioctl   r\   r7   c                     dS )z"
        @see: L{os.read}
        Nr6   )r^   limits     r8   readz_IInputOutputSystem.read   r\   r7   c                     dS )z#
        @see: L{os.write}
        Nr6   )r^   datas     r8   writez_IInputOutputSystem.write   r\   r7   c                     dS )z#
        @see: L{os.close}
        Nr6   )r^   s    r8   closez_IInputOutputSystem.close   r\   r7   c                     dS )a  
        Send a datagram to a certain address.

        @param datagram: The payload of a UDP datagram 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: The local address from which the datagram was sent.
        @rtype: L{tuple} of (L{bytes}, L{int})
        Nr6   )datagramaddresss     r8   sendUDPz_IInputOutputSystem.sendUDP   r\   r7   c                     dS )af  
        Return a socket which can be used to receive datagrams sent to the
        given address.

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

        @param host: The IPv4 address at which the datagram will be received.
        @type host: L{bytes}

        @param port: The UDP port number at which the datagram will be
            received.
        @type port: L{int}

        @return: A L{socket.socket} which can be used to receive the specified
            datagram.
        Nr6   )filenohostports      r8   
receiveUDPz_IInputOutputSystem.receiveUDP   r\   r7   )rW   )NN)r&   r'   r(   r)   r   O_RDWR
O_NONBLOCK	O_CLOEXECr[   rb   re   rh   rj   rn   rs   r6   r7   r8   rV   rV      s         
 Y+,,F344J	122I   
   
  
  
  
      r7   rV   c                       e Zd ZdZ eej                  Z eej                  Z eej                  Z eej	                  Z	 ee
j                  Zej        Zej        Z eedd          ZdS )_RealSystemz
    An interface to the parts of the operating system which L{TuntapPort}
    relies on.  This is most of an implementation of L{_IInputOutputSystem}.
    rv   i   N)r&   r'   r(   r)   staticmethodosr[   re   rh   rj   fcntlrb   rt   ru   getattrrv   r6   r7   r8   rx   rx      s         
 <  D<  DL""EL""EL%%EYFJ K33IIIr7   rx   c                       e Zd ZdZdZddZdefdZd Zd	 Z	d
 Z
d Zd Zd Zd Zd Z e edddd          e          d             ZddZd Zd ZdS )r   zH
    A Port that reads and writes packets from/to a TUN/TAP-device.
    i   r%   Nc                    t           j                            |          rd| _         t          j        | _        n9d| _         t          j        | _        t          j                            |          sJ |t                      }|| _
        t          j                            | |           || _        || _        || _        |                     | j                  }| d| j        j         d| _        d S )Nr   r   z ())r   IEthernetProtocol
providedByr   r+   _moder*   r   IRawPacketProtocolrx   _systemr   FileDescriptorrF   	interfaceprotocolmaxPacketSize_getLogPrefixr;   logstr)rD   r   protor   reactorsystem	logPrefixs          r8   rF   zTuntapPort.__init__   s    %0077 	<DM$,DJJDM$,DJ)44U;;;;;> ]]F((w777"*&&t}55	"88djo888r7   returnc                     t          | j        j                  f}| j        r|dz   }n|dz   }|| j        j        | j        fz   }d|z  S )N) )znot z<%s %slistening on %s/%s>)r   r   	__class__	connectedr   r;   r   )rD   argss     r8   __repr__zTuntapPort.__repr__  sV    !3DM4K!L!L N> 	$%<DD)#Dtz77*T11r7   c                     |                                   | j                            |            |                                  dS )z
        Create and bind my socket, and begin listening on it.

        This must be called after creating a server to begin listening on the
        specified tunnel.
        N)_bindSocketr   makeConnectionstartReadingrC   s    r8   startListeningzTuntapPort.startListening  sD     	$$T***r7   c                 x   | j         j        | j         j        z  | j         j        z  }t	          j        dt          fz  ||j                  }| j                             t          |          }| j         
                    |t          |          }t          ||dt                                       d                    S )af  
        Open the named tunnel using the given mode.

        @param name: The name of the tunnel to open.
        @type name: L{bytes}

        @param mode: Flags from L{TunnelFlags} with exactly one of
            L{TunnelFlags.IFF_TUN} or L{TunnelFlags.IFF_TAP} set.

        @return: A L{_TunnelDescription} representing the newly opened tunnel.
        z%dsHN    )r   rt   rv   ru   structpack	_IFNAMSIZrB   r[   _TUN_KO_PATHrb   
_TUNSETIFFrT   strip)rD   r;   rZ   flagsconfigrp   results          r8   _openTunnelzTuntapPort._openTunnel  s     #dl&<<t|?VVVyl2D$*EE""<77##FJ??!&&)*<*B*B7*K*KLLLr7   c                 :   t          j        d| j        j        | j                   	 |                     | j        | j        t          j        z            \  }}n-# t          $ r }t          j        d| j        |          d}~ww xY w|| _        || _        d| _        dS )z"
        Open the tunnel.
        z&%(protocol)s starting on %(interface)s)formatr   r   Nr   )r   msgr   r   r   r   r   r   r2   OSErrorr   CannotListenError_filenor   )rD   rp   r   es       r8   r   zTuntapPort._bindSocket)  s     	;],n	
 	
 	
 	

	C $ 0 0
[-B B! !FII  	C 	C 	C)$BBB	C #s   0A 
B#A>>Bc                     | j         S r>   )r   rC   s    r8   rp   zTuntapPort.fileno>  s
    |r7   c                    d}|| j         k     r	 | j                            | j        | j                  }nM# t
          $ r6}|j        t          j        t          j        t          j	        fv rY d}~dS  d}~wt          $ r  w xY w|t          |          z  }	 | j                            |d           nB# t          $ r5 t          | j        j                  }t!          j        dd| d           Y nw xY w|| j         k     dS dS )z=
        Called when my socket is ready for reading.
        r   N)partialzUnhandled exception from z.datagramReceived)maxThroughputr   re   r   r   r   errnoEWOULDBLOCKEAGAINEINTRBaseExceptionlenr   datagramReceivedr   r   r   err)rD   re   rg   r   clss        r8   doReadzTuntapPort.doReadA  s>    T'''|((t7IJJ   7u0%,LLLFFFFF    CIIDR..tQ.????  R R R()@AAP#PPPQQQQQR T'''''''s,   %5 
A?*A0/A00A?B2 2<C10C1c                     	 | j                             | j        |          S # t          $ r5}|j        t          j        k    r|                     |          cY d}~S  d}~ww xY w)z
        Write the given data as a single datagram.

        @param datagram: The data that will make up the complete datagram to be
            written.
        @type datagram: L{bytes}
        N)r   rh   r   r   r   r   )rD   rl   r   s      r8   rh   zTuntapPort.writeX  ss    	<%%dlH=== 	 	 	w%+%%zz(++++++++	s    " 
A!)AA!AA!c                 V    |                      d                    |                     dS )z
        Write a datagram constructed from a L{list} of L{bytes}.

        @param seq: The data that will make up the complete datagram to be
            written.
        @type seq: L{list} of L{bytes}
        r7   N)rh   join)rD   seqs     r8   writeSequencezTuntapPort.writeSequenceg  s&     	

388C==!!!!!r7   c                     |                                   | j        r| j        S | j        r3t	          j        | j        d| j                  | _        d| _        | j        S t          j	        d          S )z
        Stop accepting connections on this port.

        This will shut down my socket and call self.connectionLost().

        @return: A L{Deferred} that fires when this port has stopped.
        r   TN)
stopReadingdisconnecting_stoppedDeferredr   r   
deferLaterr   connectionLostr   succeedrC   s    r8   stopListeningzTuntapPort.stopListeningq  sw     	 		'((^ 	'$(Oa!4% %D! "&D((=&&&r7   Twisted   r   c                 h    |                                                      t          j                   dS )zN
        Close this tunnel.  Use L{TuntapPort.stopListening} instead.
        N)r   
addErrbackr   r   rC   s    r8   loseConnectionzTuntapPort.loseConnection  s,    
 	''00000r7   c                 
   t          j        d| j        z             t          j                            | |           | j                                         d| _        | j	        
                    | j                   d| _        dS )zY
        Cleans up my socket.

        @param reason: Ignored.  Do not use this.
        z(Tuntap %s Closed)r   N)r   r   r   r   r   r   r   doStopr   r   rj   r   )rD   reasons     r8   r   zTuntapPort.connectionLost  ss     	$t~5666..tV<<<4<(((r7   c                     | j         S )zK
        Returns the name of my class, to prefix log entries with.
        )r   rC   s    r8   r   zTuntapPort.logPrefix  s     {r7   c                 6    t          | j        | j                  S )z
        Get the local address of this L{TuntapPort}.

        @return: A L{TunnelAddress} which describes the tunnel device to which
            this object is bound.
        @rtype: L{TunnelAddress}
        )r   r   r   rC   s    r8   getHostzTuntapPort.getHost  s     TZ888r7   )r%   NNr>   )r&   r'   r(   r)   r   rF   strr   r   r   r   rp   r   rh   r   r   r   r
   r   r   r   r   r6   r7   r8   r   r      s<         M9 9 9 9*2# 2 2 2 2	 	 	M M M$  *  R R R.  " " "' ' '( Z	2q!,,m<<1 1 =<1     9 9 9 9 9r7   r   )6r)   r   r{   rz   platformr   rK   collectionsr   typingr   zope.interfacer   r   r   
constantlyr   r	   incrementalr
   twisted.internetr   r   r   r   r   twisted.pairr   r   twisted.pythonr   twisted.python.deprecater   twisted.python.reflectr   twisted.python.utilr   r   __all__r   machine
startswithr   
_TUNGETIFFr   r   IAddressr   rT   rV   rx   IListeningPortr   r   r6   r7   r8   <module>r      s/  
    				    " " " " " "       < < < < < < < < < < * * * * * * * *       E E E E E E E E E E E E E E & & & & & & & &       / / / / / / 5 5 5 5 5 5 ; ; ; ; ; ; ; ;   	H(""x$$U++ #x$$W-- #
 JJJJJ( ( ( ( (% ( ( (B Z !!&, &, &, &, &,M< &, &, "!&,R	 	 	 	 	$8-HH 	 	 	C C C C C) C C CL4 4 4 4 4 4 4 4& Z&''@9 @9 @9 @9 @9( @9 @9 ('@9 @9 @9r7   