
    Ϫf1                        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jP                         dk(  s@ ejP                         jS                  d      s  ejP                         jS                  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jf                         G d# d$ejh                               Z5y)%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y)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     5/usr/lib/python3/dist-packages/twisted/pair/tuntap.pyr   r   6   s      6"G6"Gf%J!&)NV$I (Mv&K'LV$I (M'L'Lr7   r   c                   >    e Zd ZdZdZdd fdfZed        Zd Zd Z	y	)
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
    DII 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     yyr7   c                      || _         || _        y)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                 \    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   s1     	&'		
 $))$U++r7   N)
r&   r'   r(   r)   compareAttributesshowAttributespropertyr:   rF   rO   r6   r7   r8   r   r   W   s;     /56?N 	
,r7   r   c                       e Zd ZdZy)_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                   n    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y)_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                      y)z"
        @see: L{os.open}
        Nr6   )filenamer?   modes      r8   openz_IInputOutputSystem.open       r7   Nc                      y)z&
        @see: L{fcntl.ioctl}
        Nr6   )fdoptargmutate_flags       r8   ioctlz_IInputOutputSystem.ioctl   r[   r7   c                      y)z"
        @see: L{os.read}
        Nr6   )r]   limits     r8   readz_IInputOutputSystem.read   r[   r7   c                      y)z#
        @see: L{os.write}
        Nr6   )r]   datas     r8   writez_IInputOutputSystem.write   r[   r7   c                      y)z#
        @see: L{os.close}
        Nr6   )r]   s    r8   closez_IInputOutputSystem.close   r[   r7   c                      y)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                      y)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   )i  )NN)r&   r'   r(   r)   r   O_RDWR
O_NONBLOCK	O_CLOEXECrZ   ra   rd   rg   ri   rm   rr   r6   r7   r8   rV   rV      sM    
 +,F34J1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y)_RealSystemz
    An interface to the parts of the operating system which L{TuntapPort}
    relies on.  This is most of an implementation of L{_IInputOutputSystem}.
    ru   i   N)r&   r'   r(   r)   staticmethodosrZ   rd   rg   ri   fcntlra   rs   rt   getattrru   r6   r7   r8   rw   rw      sq    
  D D"E"E%EYYFJ K3Ir7   rw   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y)r   zH
    A Port that reads and writes packets from/to a TUN/TAP-device.
    i   Nc                    t         j                  j                  |      rd| _         t        j                  | _        n=d| _         t        j                  | _        t        j                  j                  |      sJ |
t               }|| _
        t        j                  j                  | |       || _        || _        || _        | j#                  | j                        }| d| j
                  j$                   d| _        y )Nr   r   z ())r   IEthernetProtocol
providedByr   r+   _moder*   r   IRawPacketProtocolrw   _systemr   FileDescriptorrF   	interfaceprotocolmaxPacketSize_getLogPrefixr;   logstr)rD   r   protor   reactorsystem	logPrefixs          r8   rF   zTuntapPort.__init__   s    %%007DM$,,DJDM$,,DJ))44U;;;> ]F((w7"*&&t}}5	"2djjoo%6a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__  sY    !3DMM4K4K!L N>>%<D)#Dtzz77*T11r7   c                 z    | j                          | j                  j                  |        | j                          y)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  s.     	$$T*r7   c                    | j                   j                  | j                   j                  z  | j                   j                  z  }t	        j
                  dt        fz  ||j                        }| j                   j                  t        |      }| j                   j                  |t        |      }t        ||dt         j                  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   rs   ru   rt   structpack	_IFNAMSIZrB   rZ   _TUN_KO_PATHra   
_TUNSETIFFrT   strip)rD   r;   rY   flagsconfigro   results          r8   _openTunnelzTuntapPort._openTunnel  s     ##dll&<&<<t||?V?VVVyl2D$**E""<7##FJ?!&&)*<*B*B7*KLLr7   c                 t   t        j                  d| j                  j                  | j                         	 | j                  | j                  | j                  t        j                  z        \  }}|| _        || _        d| _        y# t        $ r&}t        j                  d| j                  |      d}~ww xY w)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   ro   r   es       r8   r   zTuntapPort._bindSocket)  s     	;]],,nn	

	C $ 0 0

[-B-B B!FI #  	C))$BB	Cs   :B 	B7!B22B7c                     | j                   S r>   )r   rC   s    r8   ro   zTuntapPort.fileno>  s    ||r7   c                 H   d}|| j                   k  rn	 | j                  j                  | j                  | j                        }|t        |      z  }	 | j                  j                  |d       || j                   k  rmyy# t
        $ rF}|j                  t        j                  t        j                  t        j                  fv rY d}~y d}~wt        $ r  w xY w# t        $ r< t        | j                  j                        }t!        j"                  dd| d       Y w xY w)z=
        Called when my socket is ready for reading.
        r   N)partialzUnhandled exception from z.datagramReceived)maxThroughputr   rd   r   r   r   errnoEWOULDBLOCKEAGAINEINTRBaseExceptionlenr   datagramReceivedr   r   r   err)rD   rd   rf   r   clss        r8   doReadzTuntapPort.doReadA  s     T'''||((t7I7IJ CIDR..tQ.? T'''  77u00%,,LL   ! R()@)@A 9#>OPQRs0   0B C 	C
;C
CCAD! D!c                     	 | j                   j                  | j                  |      S # t        $ r9}|j                  t        j
                  k(  r| j                  |      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   rg   r   r   r   r   )rD   rk   r   s      r8   rg   zTuntapPort.writeX  sT    	<<%%dllH== 	ww%++%zz(++	s    %( 	A*-A%A*$A%%A*c                 D    | j                  dj                  |             y)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)rg   join)rD   seqs     r8   writeSequencezTuntapPort.writeSequenceg  s     	

388C=!r7   c                    | j                          | j                  r| j                  S | j                  rCt	        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  ss     	(((^^$(OOa!4!4%D! "&D(((==&&r7   Twisted   r   c                 ^    | j                         j                  t        j                         y)zN
        Close this tunnel.  Use L{TuntapPort.stopListening} instead.
        N)r   
addErrbackr   r   rC   s    r8   loseConnectionzTuntapPort.loseConnection  s    
 	''0r7   c                 "   t        j                  d| j                  z         t        j                  j                  | |       | j                  j                          d| _        | j                  j                  | j                         d| _        y)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   ri   r   )rD   reasons     r8   r   zTuntapPort.connectionLost  sd     	$t~~5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                 B    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     TZZ88r7   )r%   NNr>   )r&   r'   r(   r)   r   rF   strr   r   r   r   ro   r   rg   r   r   r   r
   r   r   r   r   r6   r7   r8   r   r      s~     M9*2# 2	M$*R."'( 	2q!,m<1 =19r7   r   )6r)   r   rz   ry   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   rw   IListeningPortr   r   r6   r7   r8   <module>r      sE  
   	    "  < < *  E E &  / 5 ; 	H("x$$U+x$$W- JJJJ(% (B Z  !&,M< &, "&,R	$8-H 	C) CL4 4& Z&&'@9(( @9 (@9r7   