U
    Ad+$                     @   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                   @   s   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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_vlanc                 C   s
   d| j kS )NZwlanr)   r&   r!   r!   r"   is_wlanJ   s    zIfstate.is_wlanN)__name__
__module____qualname____doc__r#   propertyboolr'   r(   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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#   Z   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   r6   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dictr7   )r    r8   Zifindex
ifs_by_maclineZcurifZdevtoksr   Zcapsr   Znd6_optsipir!   r!   r"   parse^   s    










zIfconfig.parsec                 C   s   | j S r5   )r6   r&   r!   r!   r"   ifs_by_name   s    zIfconfig.ifs_by_namec                 C   s   | j S r5   )r7   r&   r!   r!   r"   rU      s    zIfconfig.ifs_by_mac)rW   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   rP   Zwith_prefixlenrF   rX   )r    rW   r]   rX   r`   ra   r!   r!   r"   rQ      s"    
zIfconfig._parse_inetc                 C   s4   t dt|D ] }|| dkr||d    S qd S )Nr?   ra   r;   )rS   rE   )r    rW   rY   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-localr\   r_   z
site-local)ra   scope)rF   rc   r   Zis_link_localZis_site_localrb   rX   )r    rW   re   Zip6restra   rX   r!   r!   r"   rR      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   )rN   rF   rE   rS   rP   )r    rW   r   Zrettr!   r!   r"   rK     s    
zIfconfig._parse_flagsN)r.   r/   r0   r1   r#   r   rb   r   r   r   r   rZ   r[   rU   rC   r
   rT   rQ   rc   rR   rK   r!   r!   r!   r"   r4   O   s   
&mr4   )rL   rN   collectionsr   	functoolsr   Z	ipaddressr   r   r   typingr   r   r	   r
   r   Z	cloudinitr   ZloggingZ	getLoggerr.   ZLOGZMAC_REr   r4   r!   r!   r!   r"   <module>   s   
: