o
    w7e#                     @   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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_loopback1      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_physical5   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_bondB   r1   zIfstate.is_bondc                 C   s   d| j v p	| ji kS )Nr   )r   r   r'   r!   r!   r"   is_vlanF   r)   zIfstate.is_vlanN)__name__
__module____qualname____doc__r#   propertyboolr(   r,   r0   r3   r4   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#   V   s   
zIfconfig.__init__textr$   c                 C   s  d}t t}| D ]}t|dkrq
|d dvr;|d7 }| d }|dr/|dd }t|}||_|| j|< |	 
  }t|dkrx|d drx| |}|i krxt|d |_|d	 |_d
|v ro|d
 |_d|v rx|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r4||dd d |_|d dkrRtd|d }t|dkrR|d d|_|d dkr^|d |_|d dkrv| |}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   )	    :Nz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linecurifdevtoksr   capsr   nd6_optsipir!   r!   r"   parseZ   s   










zIfconfig.parsec                 C   s   | j S r<   )r>   r'   r!   r!   r"   ra      s   zIfconfig.ifs_by_macre   c                 C   s   d }d|d v r!t |d }t|j}d|v r ||dd  }n"ttt|d d}d|v r9||dd  }t d|d |f }|jdd }t|j|||dfS )N/rB   	broadcast   r   %s/%s)netmaskrl   	prefixlen)	r   strro   r   r   r[   with_prefixlenrQ   rh   )r    re   rl   rh   ro   rp   r!   r!   r"   r\      s$   
zIfconfig._parse_inetc                 C   s4   t dt|D ]}|| dkr||d    S qd S )NrF   rp   rB   )r^   rP   )r    re   ri   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%rB   z
link-localrk   rn   z
site-local)rp   scope)rQ   rs   r   is_link_localis_site_localrq   rh   )r    re   ru   ip6restrp   rh   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 )NrE   rB   rI   r   r   TFrF   r   r   )rY   rQ   rP   r^   r[   )r    re   r   rettr!   r!   r"   rV      s   
zIfconfig._parse_flagsN)r5   r6   r7   r8   r#   r   rq   r   r   r   r   rj   ra   rN   r
   r_   r\   rs   r]   rV   r!   r!   r!   r"   r;   K   s    
(mr;   )rW   rY   collectionsr   	functoolsr   	ipaddressr   r   r   typingr   r   r	   r
   r   	cloudinitr   logging	getLoggerr5   LOGMAC_REr   r;   r!   r!   r!   r"   <module>   s   
6