o
    x[h¦#  ã                   @   sŠ   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mZmZmZ e e¡ZG dd„ dƒZG dd	„ d	ƒZdS )
é    N)Údefaultdict)Ú	lru_cache)ÚIPv4AddressÚIPv4InterfaceÚIPv6Interface)ÚDictÚListÚOptionalÚTupleÚUnionc                   @   sr   e Zd ZdZdd„ Zedefdd„ƒZedefdd„ƒZedefd	d
„ƒZ	edefdd„ƒZ
edefdd„ƒZdS )ÚIfstatezÏ
    This class holds the parsed state of a BSD network interface.
    It is itself side-effect free.
    All methods with side-effects should be implemented on one of the
    ``BSDNetworking`` classes.
    c                 C   sp   || _ d| _i | _i | _d| _g | _g | _g | _d| _d| _	g | _
d | _d | _d | _d | _g | _i | _g | _d S )Nr   F)ÚnameÚindexÚinetÚinet6ÚupÚoptionsÚnd6ÚflagsÚmtuÚmetricÚgroupsÚdescriptionÚmediaÚstatusÚmacÚmacsÚvlanÚmembers)Úselfr   © r    úD/usr/lib/python3/dist-packages/cloudinit/distros/parsers/ifconfig.pyÚ__init__   s$   
zIfstate.__init__Úreturnc                 C   s   d| j v p	d| jv S )NÚloopbackÚlo)r   r   ©r   r    r    r!   Úis_loopback.   ó   zIfstate.is_loopbackc                 C   s0   d| j v rdS | j g kr| jrd| jv rdS dS )NÚegressTÚEthernetF)r   r   r&   r    r    r!   Úis_physical2   s
   
zIfstate.is_physicalc                 C   ó
   d| j v S )NÚbridge©r   r&   r    r    r!   Ú	is_bridge;   ó   
zIfstate.is_bridgec                 C   r,   )NÚlaggr.   r&   r    r    r!   Úis_bond?   r0   zIfstate.is_bondc                 C   s   d| j v p	| ji kS )Nr   )r   r   r&   r    r    r!   Úis_vlanC   r(   zIfstate.is_vlanN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r"   ÚpropertyÚboolr'   r+   r/   r2   r3   r    r    r    r!   r      s    r   c                
   @   sš   e Zd ZdZdd„ Zeƒ dedeeee	e
e	 f f fdd„ƒZdd	„ Zd
edeeef fdd„Zdd„ Zd
edeeef fdd„Zd
edefdd„ZdS )ÚIfconfiga8  
    A parser for BSD style ``ifconfig(8)`` output.
    For documentation here:
    - https://man.freebsd.org/ifconfig(8)
    - https://man.netbsd.org/ifconfig.8
    - https://man.openbsd.org/ifconfig.8
    All output is considered equally, and then massaged into a singular form:
    an ``Ifstate`` object.
    c                 C   s   i | _ i | _d S ©N)Ú_ifs_by_nameÚ_ifs_by_macr&   r    r    r!   r"   S   s   
zIfconfig.__init__Útextr#   c                 C   sÀ  d}t tƒ}d}| ¡ D �]Å}|sq|d dvr9|d7 }| ¡ d }| d¡r-|dd… }t|ƒ}||_|| j|< |s<q| ¡  	¡  ¡ }t
|ƒdkry|d  d¡ry|  |¡}|i kryt |d ¡|_|d	 |_d
|v rp|d
 |_d|v ry|d |_|d  d¡rŽt d|d ¡}	|j |	¡ |d dkr›t|d ƒ|_|d dkr­|| d¡d d… |_|d  d¡sÂ|d  d¡sÂ|d  d¡rÜt d|d ¡}
t
|
ƒdkrÜ| j|
d  d¡7  _|d dkrø|d |_|j |d ¡ ||d   |¡ |d dk�r|j |d ¡ ||d   |¡ |d dk�r"| j|dd… 7  _|d dk�r5|| d¡d d… |_|d dk�rSt d|d ¡}t
|ƒdk�rS|d  d¡|_|d dk�r_|d |_|d dk�rw|  |¡}t |d ¡|j|d < |d dk�r�|   |¡}t |d ¡|j!|d < |d dk�s�|d dk�r¦| j"|d 7  _"|d d k�rÒi |_#|d |j#d!< t$dt
|ƒƒD ]}|| d"k�rÐ||d  |j#d#< �q¾qt%|ƒ| _&i | j¥| j&¥S )$a  
        Parse the ``ifconfig -a`` output ``text``, into a dict of ``Ifstate``
        objects, referenced by ``name`` *and* by ``mac`` address.

        This dict will always be the same, given the same input, so we can
        ``@lru_cache()`` it. n.b.: ``@lru_cache()`` takes only the
        ``__hash__()`` of the input (``text``), so it should be fairly quick,
        despite our giant inputs.

        @param text: The output of ``ifconfig -a``
        @returns: A dict of ``Ifstate``s, referenced by ``name`` and ``mac``
        r   N)ú	ú é   ú:éÿÿÿÿzflags=r   r   r   r   zcapabilities=ú<|>r   zdescription:é   zoptions=Úec_capabilitiesÚ
ec_enabledú,ÚetherÚhwaddrzgroups:zmedia:z: r   r   r   r   zmember:z	laggport:zvlan:Úidz
interface:Úlink)'r   ÚlistÚ
splitlinesÚsplitÚendswithr   r   r<   ÚlowerÚstripÚlenÚ
startswithÚ_parse_flagsÚcopyÚdeepcopyr   r   r   r   ÚreÚappendÚintr   r   r   r   r   r   r   r   Ú_parse_inetr   Ú_parse_inet6r   r   r   ÚrangeÚdictr=   )r   r>   ÚifindexÚ
ifs_by_macÚdevÚlineÚcurifÚtoksr   Úcapsr   Únd6_optsÚipÚir    r    r!   ÚparseW   s˜   





ÿþý



€
zIfconfig.parsec                 C   s   | j S r;   )r=   r&   r    r    r!   r`   Ë   s   zIfconfig.ifs_by_macrd   c                 C   s’   d }d|d v rt |d ƒ}t|jƒ}nttt|d dƒƒƒ}t d|d |f ƒ}d|v r6|| d¡d  }|j d¡d }t|jƒ|||dœfS )Nú/rA   é   r   ú%s/%sÚ	broadcast)Únetmaskrm   Ú	prefixlen)	r   Ústrrn   r   rZ   r   Úwith_prefixlenrO   rg   )r   rd   rm   rg   rn   ro   r    r    r!   r[   Î   s   ýþzIfconfig._parse_inetc                 C   s4   t dt|ƒƒD ]}|| dkr||d    S qd S )NrE   ro   rA   )r]   rS   )r   rd   rh   r    r    r!   Ú_get_prefixlenã   s
   ÿÿzIfconfig._get_prefixlenc                 C   sÖ   d }d|d v r-d}|d   d¡\}}d|v r|  d¡d }n|  |¡}td||f ƒ}n%d|d v rCt|d ƒ}|d   d¡d }n|  |¡}td|d |f ƒ}|sZ|jrZd}n|sa|jrad}t|jƒ||dœfS )Nú%rA   z
link-localrj   rl   z
site-local)ro   Úscope)rO   rr   r   Úis_link_localÚis_site_localrp   rg   )r   rd   rt   Úip6Úrestro   rg   r    r    r!   r\   è   s$   



zIfconfig._parse_inet6c                 C   sª   t  d|d ¡}i }t|ƒdkrS|d  d¡|d< d|d v r$d|d< nd|d< tdt|ƒƒD ]#}|| d	krBt||d  ƒ|d	< q/|| d
krRt||d  ƒ|d
< q/|S )NrD   rA   rH   r   r   TFrE   r   r   )rX   rO   rS   r]   rZ   )r   rd   r   ÚretÚtr    r    r!   rU     s   
€zIfconfig._parse_flagsN)r4   r5   r6   r7   r"   r   rp   r   r   r   r   ri   r`   rM   r
   r^   r[   rr   r\   rU   r    r    r    r!   r:   H   s    
(sr:   )rV   ÚloggingrX   Úcollectionsr   Ú	functoolsr   Ú	ipaddressr   r   r   Útypingr   r   r	   r
   r   Ú	getLoggerr4   ÚLOGr   r:   r    r    r    r!   Ú<module>   s   
6