U
    Ld#                     @   s   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 d dlmZ eeZdZG dd	 d	ZG d
d dZdS )    N)defaultdict)	lru_cache)IPv4AddressIPv4InterfaceIPv6Interface)DictListOptionalTupleUnion)logz"([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}c                   @   sr   e Zd ZdZdd ZeedddZeedddZeedd	d
Z	eedddZ
eed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 kpd| jkS )NZloopbacklo)r   r   r    r!   r!   r"   is_loopback1   s    zIfstate.is_loopbackc                 C   s0   d| j krdS | j g kr,| jr,d| jkr,dS dS )NZegressTZEthernetF)r   r   r&   r!   r!   r"   is_physical5   s
    
zIfstate.is_physicalc                 C   s
   d| j kS )NZbridger   r&   r!   r!   r"   	is_bridge>   s    zIfstate.is_bridgec                 C   s
   d| j kS )NZlaggr)   r&   r!   r!   r"   is_bondB   s    zIfstate.is_bondc                 C   s   d| j kp| ji kS )Nr   )r   r   r&   r!   r!   r"   is_vlanF   s    zIfstate.is_vlanN)__name__
__module____qualname____doc__r#   propertyboolr'   r(   r*   r+   r,   r!   r!   r!   r"   r      s   r   c                   @   s   e Zd ZdZdd Ze eeeee	e
e	 f f dddZdd Zeeeef d	d
dZdd Zeeeef d	ddZeed	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#   V   s    zIfconfig.__init__)textr$   c                 C   s  d}t t}| D ]}t|dkr(q|d dkrv|d7 }| d }|dr^|dd }t|}||_|| j|< |	 
  }t|dkr|d dr| |}|i krt|d |_|d	 |_d
|kr|d
 |_d|kr|d |_|d drtd|d }	|j|	 |d dkr8t|d |_|d dkr^||dd d |_|d ds|d ds|d drt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rR| j|dd 7  _|d dkrx||dd d |_|d dkrtd|d }t|dkr|d d|_|d dkr|d |_|d dkr| |}t|d |j|d < |d dkr,|  |}t|d |j!|d < |d dksH|d dkrZ| j"|d 7  _"|d d kri |_#|d |j#d!< t$dt|D ]&}|| d"kr||d  |j#d#< qqt%|| _&| 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   )	    :Nzflags=r   r   r   r   zcapabilities=<|>r   zdescription:   zoptions=Zec_capabilitiesZ
ec_enabled,ZetherZhwaddrzgroups:zmedia:z: r   r   r   r   zmember:z	laggport:zvlan:idz
interface:link)'r   list
splitlineslensplitendswithr   r   r5   lowerstrip
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dictr6   )r    r7   Zifindex
ifs_by_maclineZcurifZdevtoksr   Zcapsr   Znd6_optsipir!   r!   r"   parseZ   s    










zIfconfig.parsec                 C   s   | j S r4   )r6   r&   r!   r!   r"   rT      s    zIfconfig.ifs_by_mac)rV   r$   c                 C   s   d }d|d krBt |d }t|j}d|kr||dd  }nDttt|d d}d|krr||dd  }t d|d |f }|jdd }t|j|||dfS )N/r:   	broadcast   r   %s/%s)netmaskr[   	prefixlen)	r   strr^   r   r   rO   Zwith_prefixlenrE   rW   )r    rV   r[   rW   r^   r_   r!   r!   r"   rP      s"    
zIfconfig._parse_inetc                 C   s4   t dt|D ] }|| dkr||d    S qd S )Nr>   r_   r:   )rR   rD   )r    rV   rX   r!   r!   r"   _get_prefixlen   s    zIfconfig._get_prefixlenc                 C   s   d }d|d krZd}|d  d\}}d|kr>| dd }n
| |}td||f }nJd|d krt|d }|d  dd }n| |}td|d |f }|s|jrd}n|s|jrd}t|j||dfS )N%r:   z
link-localrZ   r]   z
site-local)r_   scope)rE   ra   r   Zis_link_localZis_site_localr`   rW   )r    rV   rc   Zip6restr_   rW   r!   r!   r"   rQ      s$    



zIfconfig._parse_inet6c                 C   s   t d|d }i }t|dkr|d d|d< d|d krHd|d< nd|d< tdt|D ]F}|| d	krt||d  |d	< q^|| d
kr^t||d  |d
< q^|S )Nr=   r:   r?   r   r   TFr>   r   r   )rM   rE   rD   rR   rO   )r    rV   r   Zrettr!   r!   r"   rJ      s    
zIfconfig._parse_flagsN)r-   r.   r/   r0   r#   r   r`   r   r   r   r   rY   rT   rB   r
   rS   rP   ra   rQ   rJ   r!   r!   r!   r"   r3   K   s   
&mr3   )rK   rM   collectionsr   	functoolsr   Z	ipaddressr   r   r   typingr   r   r	   r
   r   Z	cloudinitr   ZloggingZ	getLoggerr-   ZLOGZMAC_REr   r3   r!   r!   r!   r"   <module>   s   
6