o
    f#                     @   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 ]}t|dkrq|d dvr=|d7 }| d }|dr1|dd }t|}||_|| j|< |s@q|	 
  }t|dkr}|d dr}| |}|i kr}t|d |_|d	 |_d
|v rt|d
 |_d|v r}|d |_|d drtd|d }	|j|	 |d dkrt|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r&| j|dd 7  _|d dkr9||dd d |_|d dkrWtd|d }t|dkrW|d d|_|d dkrc|d |_|d dkr{| |}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ri |_#|d |j#d!< t$dt|D ]}|| d"kr||d  |j#d#< qq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lensplitendswithr   r   r<   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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_prefixlenrP   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]   rO   )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)rP   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   rP   rO   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