MMCT TEAM
Server IP : 2a02:4780:11:1373:0:3017:be17:10  /  Your IP : 216.73.216.55
Web Server : LiteSpeed
System : Linux in-mum-web1273.main-hosting.eu 4.18.0-553.37.1.lve.el8.x86_64 #1 SMP Mon Feb 10 22:45:17 UTC 2025 x86_64
User : u806862359 ( 806862359)
PHP Version : 8.2.27
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : OFF  |  Python : OFF
Directory (0755) :  /lib/frr/__pycache__/

[  Home  ][  C0mmand  ][  Upload File  ]

Current File : //lib/frr/__pycache__/ospfclient.cpython-36.pyc
3

��sg}��@sBddlZddlZddlZddlZddlZddlZddlZddlmZmZddl	m
ZdZej
e�ZdZdZdZdZdZej
e�ZdZdZd	Zd
ZdZdZd
ZdZdZdZedeedfedefedefeddedd�fedgedhediedjedki
ZdZ dZ!d Z"d!Z#d"Z$d#Z%d$Z&d%Z'd&Z(d'Z)d(Z*e!dle"dme#d-d.edd�fe$d/d.edd�fe%dne&doe'dpe(dqe)dre*dsi
Z+dZ,dtZ-duZ.dvZ/dwZ0dxZ1dyZ2dzZ3d{Z4d|Z5d}Z6e,d9e-d:e.d;e/d<e0d=e1d>e2d?e3d@e4dAe5dBe6dCiZ7iZ8e8j9e�e8j9e+�dDdE�e8j:�D�Z;dFdE�e8j:�D�Z<dGdE�e<j:�D�Z=dHdI�Z>dJdK�Z?GdLdM�dMe@�ZAGdNdO�dOe@�ZBGdPdQ�dQe@�ZCdZDdZEdZFd	ZGd
ZHdZIdZJd
ZKdZLdZMdZNd ZOdRdS�ZPdZQdZRdZSd	ZTd
ZUdZVdZWd
ZXdTdU�ZYdZZdZ[dZ\d	Z]d
Z^dZ_dZ`d
ZadZbdZcdVdW�ZdGdXdY�dY�ZeGdZd[�d[�ZfGd\d]�d]ef�Zgd~d^d_�Zhd`da�Zidbdc�Zjekddk�r>ej�Zlejmel�dS)�N)�Event�Lock)�
ip_addressz>BBHLz>HBB��z	>HBBIILHH�������	��REGISTER_OPAQUETYPE�BBxx�UNREGISTER_OPAQUETYPEZREGISTER_EVENTZ	SYNC_LSDBZORIGINATE_REQUEST�>II�DELETE_REQUEST�>IBBxBL�MSG_SYNC_REACHABLE��MSG_SYNC_ISM�MSG_SYNC_NSM�MSG_SYNC_ROUTER_ID�
���
�������REPLY�bxxx�READY_NOTIFY�>BBxxIZLSA_UPDATE_NOTIFY�>IIBxxxZLSA_DELETE_NOTIFY�NEW_IF�DEL_IF�>I�
ISM_CHANGE�
NSM_CHANGE�>IIIBxxx�REACHABLE_CHANGE�>HH�ROUTER_ID_CHANGE�OSPF_API_OK�OSPF_API_NOSUCHINTERFACE�OSPF_API_NOSUCHAREA�OSPF_API_NOSUCHLSA�OSPF_API_ILLEGALLSATYPE�OSPF_API_OPAQUETYPEINUSE� OSPF_API_OPAQUETYPENOTREGISTERED�OSPF_API_NOTREADY�OSPF_API_NOMEMORY�OSPF_API_ERROR�OSPF_API_UNDEFcCsi|]\}}|d|�qS)r�)�.0�k�vr=r=�./usr/lib/frr/ospfclient.py�
<dictcomp>�srBcCsi|]\}}|d|�qS)rr=)r>r?r@r=r=rArB�scCsi|]\}}tj|�|�qSr=)�struct�calcsize)r>r?r@r=r=rArB�scCstj|t|��S)N)�msg_name�get�str)�mtr=r=rA�api_msgname�srIcCstj|t|��S)N)�msg_errnamerFrG)�ecoder=r=rA�api_errname�srLc@seZdZdS)�APIErrorN)�__name__�
__module__�__qualname__r=r=r=rArM�srMc@seZdZdS)�MsgTypeErrorN)rNrOrPr=r=r=rArQ�srQc@seZdZdS)�SeqNumErrorN)rNrOrPr=r=r=rArR�srRcCs@tdtdtdtdtdtdtdtdtd	t	d
t
di}|j|t|��S)Nz
LSA:ROUTERzLSA:NETWORKzLSA:SUMMARYzLSA:ASBR_SUMMARYzLSA:AS_EXTERNALzLSA:GROUP_MEMBERzLSA:AS_NSSAzLSA:EXTERNAL_ATTRIBUTESzLSA:OPAQUE_LINKzLSA:OPAQUE_AREAz
LSA:OPAQUE_AS)
�LSA_TYPE_ROUTER�LSA_TYPE_NETWORK�LSA_TYPE_SUMMARY�LSA_TYPE_ASBR_SUMMARY�LSA_TYPE_AS_EXTERNAL�LSA_TYPE_GROUP_MEMBER�LSA_TYPE_AS_NSSA�LSA_TYPE_EXTERNAL_ATTRIBUTES�LSA_TYPE_OPAQUE_LINK�LSA_TYPE_OPAQUE_AREA�LSA_TYPE_OPAQUE_ASrFrG)�lsa_type�namesr=r=rA�lsa_typename�sr`cCs4tdtdtdtdtdtdtdtdi}|j|t	|��S)	N�ISM_DEPENDUPON�ISM_DOWN�ISM_LOOPBACK�ISM_WAITING�ISM_POINTTOPOINT�ISM_DROTHER�
ISM_BACKUP�ISM_DR)
rarbrcrdrerfrgrhrFrG)�stater_r=r=rA�ism_name�srjcCs<tdtdtdtdtdtdtdtdtd	t	d
i
}|j
|t|��S)N�NSM_DEPENDUPON�NSM_DELETED�NSM_DOWN�NSM_ATTEMPT�NSM_INIT�
NSM_TWOWAY�NSM_EXSTART�NSM_EXCHANGE�NSM_LOADING�NSM_FULL)rkrlrmrnrorprqrrrsrtrFrG)rir_r=r=rA�nsm_name�sruc@s eZdZdZdd�Zdd�ZdS)�WithNothingz<An object that does nothing when used with `with` statement.c�sdS)Nr=)�selfr=r=rA�
__aenter__szWithNothing.__aenter__c�sdS)Nr=)rw�args�kwargsr=r=rA�	__aexit__szWithNothing.__aexit__N)rNrOrP�__doc__rxr{r=r=r=rArvsrvc@s�eZdZdd�Zedd��Zd.dd�Zd	d
�Zdd�Ze	d
d��Z
dd�Zdd�Zed0dd��Z
dd�Zdd�Zd2dd�Zdd�Zed d!��Zed"d#��Zd$d%�Zd&d'�Zd(d)�Zd*d+�Zd,d-�ZdS)3�
OspfApiClientcCsdj|j�S)NzOspfApiClient({}))�format�server)rwr=r=rA�__str__szOspfApiClient.__str__cCs�tjtjtjd�}y�|jtjtjd�|jd|f�tjtjtjd�}y,|jtjtjd�|jd|df�||fStk
r�|j��YnXWntk
r�|j��YnXdS)Nrrr)	�socketZAF_INETZSOCK_STREAMZ
setsockoptZ
SOL_SOCKETZSO_REUSEADDRZbind�	Exception�close)�port�s1�s2r=r=rA�_get_bound_socketssz OspfApiClient._get_bound_sockets�	localhostNcCs
d|_d|_d|_d|_d|_|_|_||_|dk	r<|nt�|_	t
�|_d}d}x�t||dd�D]�}y,t
jd|||d�|j|�\|_|_PWqftk
r�}z@|jtjks�||kr�t
jd|||��t
jd	|||d�WYdd}~XqfXqfWd
�std��dS)afA client connection to OSPF Daemon using the OSPF API

        The client object is not created in a connected state.  To connect to the server
        the `connect` method should be called.  If an error is encountered when sending
        messages to the server an exception will be raised and the connection will be
        closed.  When this happens `connect` may be called again to restore the
        connection.

        Args:
            server: hostname or IP address of server default is "localhost"
            handlers: dict of message handlers, the key is the API message
                type, the value is a function. The functions signature is:
                `handler(msg_type, msg, msg_extra, *params)`, where `msg` is the
                message data after the API header, `*params` will be the
                unpacked message values, and msg_extra are any bytes beyond the
                fixed parameters of the message.
        Raises:
            Will raise exceptions for failures with various `socket` modules
            functions such as `socket.socket`, `socket.setsockopt`, `socket.bind`.
        rNi�i��rz%s: binding to ports %s, %srz%s: binding port %s error %sz%s: ports %s, %s in use.Fz*Should not reach this code execution point)�_seq�_s�_as�_ls�_ar�_r�_wr�dict�handlersr�
write_lock�range�logging�debugr��OSError�errnoZ
EADDRINUSE�warning�AssertionError)rwrr�Z	PORTSTARTZPORTENDr��errorr=r=rA�__init__)s**zOspfApiClient.__init__c�s�tjd|�tj�}|jj�yNtjd|�|j|j|jdf�IdHtjd|�|j	|j�IdH\|_
}Wn$tk
r�|j�IdH�YnXtjd|�tj
|jd�IdH\|_|_tj
|j
d�IdH\|_}d|_dS)Nz%s: connect to OSPF APIz$%s: connecting sync socket to serveri/
z!%s: accepting connect from serverz%s: success)Zsockr)r�r��asyncio�get_event_loopr�ZlistenZsock_connectr�rZsock_acceptr�r��
_close_lockedZopen_connectionr�r�r�r�)rw�loop�_r=r=rA�_connect_lockedWs
zOspfApiClient._connect_lockedc
�s2|j4IdH�|j�IdHWdQIdHRXdS)N)r�r�)rwr=r=rA�connectlszOspfApiClient.connectcCs
|jdkS)z!True if the connection is closed.r)r�)rwr=r=rA�closedpszOspfApiClient.closedc�s�tjd|�|jrP|jr:|jj�|jj�IdHd|_n
|jj�d|_d|_|jdks^t�|jrz|jj�d|_d|_	|j
r�|j
j�d|_
d|_dS)Nz%s: closingr)r�r�r�r�r�Zwait_closedr�r�r�r�r�r�)rwr=r=rAr�us$



zOspfApiClient._close_lockedc
�s2|j4IdH�|j�IdHWdQIdHRXdS)N)r�r�)rwr=r=rAr��szOspfApiClient.closerc�s�y�|jt�IdH}tjt|�\}}}}|dkr<tdj|���|dkrRtjd|�n||krjt	dj||���|r~|j|�IdHnd}||fSt
jk
r�t�YnXdS)aWRead an OSPF API message from the socket `r`

        Args:
            r: socket to read msg from
            expseq: sequence number to expect or -1 for any.
        Raises:
            Will raise exceptions for failures with various `socket` modules,
            Additionally may raise SeqNumError if unexpected seqnum is received.
        Nrz'received unexpected OSPF API version {}z&_msg_read: got seq: 0x%x on async readzrx {} != {}����)
Zreadexactly�FMT_APIMSGHDR_SIZErC�unpack�
FMT_APIMSGHDRr�r~r�r�rRr�ZIncompleteReadError�EOFError)�rZexpseq�mhr@rH�l�seq�msgr=r=rA�	_msg_read�szOspfApiClient._msg_readc�stj|jd�IdHS)z�Read a message from the async notify channel.

        Raises:
            May raise exceptions for failures with various `socket` modules.
        rNr�)r}r�r�)rwr=r=rA�msg_read�szOspfApiClient.msg_readc�s�tjd|t|�|j�tjtd|t|�|j�}|j}|d|_y�|j4IdH�>|j	j
||�|j	j�IdHtj
|j|�IdH\}}WdQIdHRX|tkr�tdjt|�tt����tjtt|�dStk
r�|j�IdH�YnXdS)a
Send a message to OSPF API and wait for error code reply.

        Args:
            mt: the messaage type
            mp: the message payload
        Returns:
            error: an OSPF_API_XXX error code, 0 for OK.
        Raises:
            Raises SeqNumError if the synchronous reply is the wrong sequence number;
            MsgTypeError if the synchronous reply is not MSG_REPLY. Also,
            may raise exceptions for failures with various `socket` modules,

            The connection will be closed.
        zSEND: %s: sending %s seq 0x%xrNzrx {} != {}r)r�r�rIr�rC�packr��lenr�r��writeZdrainr}r�r��	MSG_REPLYrQr~r��msg_fmtr�r�)rwrH�mpr�r�r=r=rA�msg_send�s 
(zOspfApiClient.msg_send�rc�s2|j||�IdH}|r.tdjt|�t|����dS)a�Send a message to OSPF API and wait for error code reply.

        Args:
            mt: the messaage type
            mp: the message payload
        Raises:
            APIError if the server replies with an error.

            Also may raise exceptions for failures with various `socket` modules,
            as well as MsgTypeError if the synchronous reply is incorrect.
            The connection will be closed for these non-API error exceptions.
        Nz{} error {})r�rMr~rIrL)rwrHr�rKr=r=rA�msg_send_raises�s
zOspfApiClient.msg_send_raisesc�s�|tkrtjd||�dSt|}t|}tj||d|��}||d�}||jkrjtjd|t|��dStjd|t|��|j||||f|��IdHdS)Nz#RECV: %s: unknown async msg type %sz%RECV: %s: no handlers for msg type %sz RECV: %s: calling handler for %s)r�r�r��msg_sizerCr�r�rI)rwrHr��fmtZsz�tup�extrar=r=rA�handle_async_msg�s
zOspfApiClient.handle_async_msgcGsP|sdSd}x>|D]6}d|ko(dkns<tdj|���|d|>O}qW|S)z.Return a 16 bit mask for each LSA type passed.i��rr z LSA type {} out of range [1, 15]r)r�r~)�	lsa_types�mask�tr=r=rA�
lsa_type_mask�s
&zOspfApiClient.lsa_type_maskcCs>tj|�}t|�}t|r"dj|�nd}tj||||f|��S)z�Return an LSA filter.

        Return the filter message bytes based on `origin` the `areas` list and the LSAs
        types in the `lsa_types` list.
        z{}Ir)r}r�r��FMT_LSA_FILTERr~rCr�)�originZareasr�r�Znarear�r=r=rA�
lsa_filters
zOspfApiClient.lsa_filterc�sNtjd|�tjtgg�}|jt|�IdHtjd|�|jt|�IdHdS)zHRegister for all LSA notifications and request an LSDB synchronoization.zSEND: %s: request LSDB eventsNzSEND: %s: request LSDB sync)r�r�r}r��LSAF_ORIGIN_ANYr��MSG_REGISTER_EVENT�
MSG_SYNC_LSDB)rwr�r=r=rA�
req_lsdb_syncs
zOspfApiClient.req_lsdb_syncc�s tjd|�|jt�IdHdS)z(Request a dump of all reachable routers.z#SEND: %s: request reachable changesN)r�r�r�r)rwr=r=rA�req_reachable_routerssz#OspfApiClient.req_reachable_routersc�s tjd|�|jt�IdHdS)z;Request a dump of the current ISM states of all interfaces.zSEND: %s: request ISM changesN)r�r�r�r)rwr=r=rA�req_ism_states"szOspfApiClient.req_ism_statesc�s tjd|�|jt�IdHdS)z:Request a dump of the current NSM states of all neighbors.zSEND: %s: request NSM changesN)r�r�r�r)rwr=r=rA�req_nsm_states'szOspfApiClient.req_nsm_statesc�s tjd|�|jt�IdHdS)z:Request a dump of the current NSM states of all neighbors.z SEND: %s: request router ID syncN)r�r�r�r)rwr=r=rA�req_router_id_sync,sz OspfApiClient.req_router_id_sync)r�Nr�)r��)r�)rNrOrPr��staticmethodr�r�r�r��propertyr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r=r=r=rAr}s*
.&

	r}cs�eZdZdZd6�fdd�	Zdd�Zdd	�Zed
d��Zedd
��Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zd7dd �Zd!d"�Zd8d$d%�Zd&d'�Zd9d(d)�Zd*d+�Zd:d,d-�Zd;d.d/�Zd<d0d1�Zd=d2d3�Zd>d4d5�Z�ZS)?�OspfOpaqueClientaPA client connection to OSPF Daemon for manipulating Opaque LSA data.

    The client object is not created in a connected state.  To connect to the server
    the `connect` method should be called.  If an error is encountered when sending
    messages to the server an exception will be raised and the connection will be
    closed.  When this happens `connect` may be called again to restore the
    connection.

    Args:
        server: hostname or IP address of server default is "localhost"
        wait_ready: if True then wait for OSPF to signal ready, in newer versions
            FRR ospfd is always ready so this overhead can be skipped.
            default is False.

    Raises:
        Will raise exceptions for failures with various `socket` modules
        functions such as `socket.socket`, `socket.setsockopt`, `socket.bind`.
    r�Fcs�t|jt|jt|jt|jt|jt|j	t
|jt|j
i}|rB|j|t<t�j||�||_|r`t�nt�|_tititii|_td�|_d|_i|_d|_i|_t �|_!d|_"i|_#i|_$d|_%i|_&d|_'dS)Nr)(�MSG_LSA_UPDATE_NOTIFY�_lsa_change_msg�MSG_LSA_DELETE_NOTIFY�
MSG_NEW_IF�_if_msg�
MSG_DEL_IF�MSG_ISM_CHANGE�_if_change_msg�MSG_NSM_CHANGE�_nbr_change_msg�MSG_REACHABLE_CHANGE�_reachable_msg�MSG_ROUTER_ID_CHANGE�_router_id_msg�
_ready_msg�MSG_READY_NOTIFY�superr��
wait_readyrrv�
ready_lockr[r\r]�
ready_cond�ip�	router_id�router_id_change_cbZlsid_seq_num�
lsa_change_cb�opaque_change_cb�set�reachable_routers�reachable_change_cb�if_area�
ism_states�
ism_change_cb�
nsm_states�
nsm_change_cb)rwrr�r�)�	__class__r=rAr�Fs8



zOspfOpaqueClient.__init__c�s�|j4IdH��|j|j|�}|dks<tdjt|�|���tjdt|�|�t}t	j
t|||�}|j||�IdH|j
s�d|j||<WdQIdHRXdS)Nz(multiple registers for {} opaque-type {}zregister %s opaque-type %sT)r�r�rFr�r~r`r�r��MSG_REGISTER_OPAQUETYPErCr�r�r�r�)rwr^�otype�condrHr�r=r=rA�_register_opaque_dataosz&OspfOpaqueClient._register_opaque_datac�s�y\tjd�xL|j�IdH\}}|tkr<|j||�IdHqt|�}tjd|t|��qWWntk
rztj	d�dSXdS)Nz entering async msg handling loopz#ignoring unexpected msg: %s len: %sz3Got EOF from OSPF API server on async notify socketr)
r�r�r��	amsg_infor�rIr�r�r��info)rwrHr�Zmtsr=r=rA�_handle_msg_loop�s

z!OspfOpaqueClient._handle_msg_loopc
Cs(|d>|B}dd||dddtt|�fS)N�r)�FMT_LSA_HEADER_SIZEr�)r^r��oidr�Zlsidr=r=rA�_opaque_args�szOspfOpaqueClient._opaque_argscCs(tjtftj||||���}||7}|S)N)rCr��FMT_LSA_HEADERr�r�)r^r�r�r��lsar=r=rA�_make_opaque_lsa�sz!OspfOpaqueClient._make_opaque_lsac
�s�|js
t�|tkr"djt|��}n|tkr:djt|��}nd}tjd|t|�||�|j	4IdH�$|j
|j|�}d|j
||<WdQIdHRX|dkr�tjdt|�|�n|r�x|D]}	|	j
�q�WdS)Nz	ifaddr {}zarea {}rz-RECV: %s ready notify for %s opaque-type %s%sTz.RECV: dup ready received for %s opaque-type %s)r�r�r[r~r�r\r�r�r`r�r�rFr�r�)
rwrHr�r�r^r��addr�er��evtr=r=rAr��s.

zOspfOpaqueClient._ready_msgc�sL|tkr|\}}n|tkst�|dd}}tjdt|�t|�t|��dS)NrzRECV: %s ifaddr %s areaid %s)r�r�r�r�r�rIr�)rwrHr�r�ry�ifaddr�aidr=r=rAr��s
zOspfOpaqueClient._if_msgc�sVt|�}t|�}tjdt|�||t|��||j|<||j|<|jrR|j|||�dS)Nz%RECV: %s ifaddr %s areaid %s state %s)r�r�r�rIrjr�r�r�)rwrHr�r�rrrir=r=rAr��s


zOspfOpaqueClient._if_change_msgc�stt|�}t|�}t|�}tjdt|�|||t|��||jkrHi|j|<||j|||f<|jrp|j||||�dS)Nz3RECV: %s ifaddr %s nbraddr %s router_id %s state %s)r�r�r�rIrur�r�)rwrHr�r�rZnbraddrr�rir=r=rAr��s


z OspfOpaqueClient._nbr_change_msgc�s�|\}}	}
}}	}}	}
|d?d@}|tkr.d}n|tks:t�d}tjd|t|�t|�||
|�|
|f}t|t}||d�}||jkr�|j|||||||�|j	r�|j	||||||�dS)Nr���update�deletez=RECV: LSA %s msg for LSA %s in area %s seq 0x%x len %s age %s)
r�r�r�r�r�r�r�r�r�r�)rwrHr�r�rrZis_selfZ	ls_headerZlsa_ager�r^Zls_idZls_seqZls_lenr�Zts�idxZpre_lsa_sizerr=r=rAr��s*

z OspfOpaqueClient._lsa_change_msgc�s�tjdj||�|�}dd�|D�}tjdt|�|d|�||d��|jt|d|��O_|jt||d��8_tjdt|�|j�|jr�tjdt|��|j|d|�||d��IdHdS)Nz>{}IcSsg|]}t|��qSr=)r�)r>�xr=r=rA�
<listcomp>sz3OspfOpaqueClient._reachable_msg.<locals>.<listcomp>zRECV: %s added %s removed %szRECV: %s new set %szRECV: %s calling callback)	rCr�r~r�r�rIr�r�r�)rwrHr�r�ZnaddZnremoveZ
router_idsr=r=rAr�s
zOspfOpaqueClient._reachable_msgc�srt|�}tjdt|�|�|j}||kr,dS||_tjdt|�||�|jrntjdt|��|j||�IdHdS)NzRECV: %s router ID %sz,RECV: %s new router ID %s older router ID %szRECV: %s calling callback)r�r�r�rIr�r�)rwrHr�r�r�Z
old_router_idr=r=rAr�(szOspfOpaqueClient._router_id_msgc
�s�|jj|i�j|�dks td��|tkr8t|�d}}n,|tkrPdt|�}}n|tks\t�d\}}t}tj	t
|||ftj||||���}	|	|7}	|j
||	�IdHdS)a�Add an instance of opaque data.

        Add an instance of opaque data. This call will register for the given
        LSA and opaque type if not already done.

        Args:
            addr: depends on lsa_type, LINK => ifaddr, AREA => area ID, AS => ignored
            lsa_type: LSA_TYPE_OPAQUE_{LINK,AREA,AS}
            otype: (octet) opaque type
            oid: (3 octets) ID of this opaque data
            data: the opaque data
        Raises:
            See `msg_send_raises`
        TzNot Registered!rN)rr)r�rFr�r[�intr\r]�MSG_ORIGINATE_REQUESTrCr�r�r�r�r�)
rwrr^r�r��datarrrHr�r=r=rA�add_opaque_data;s z OspfOpaqueClient.add_opaque_datarc�sV|jj|i�j|�dks td��t}tjt|t|�||||�}|j||�IdHdS)a7Delete an instance of opaque data.

        Delete an instance of opaque data. This call will register for the given
        LSA and opaque type if not already done.

        Args:
            addr: depends on lsa_type, LINK => ifaddr, AREA => area ID, AS => ignored
            lsa_type: LSA_TYPE_OPAQUE_{LINK,AREA,AS}
            otype: (octet) opaque type.
            oid: (3 octets) ID of this opaque data
            flags: (octet) optional flags (e.g., OSPF_API_DEL_ZERO_LEN_LSA, defaults to no flags)
        Raises:
            See `msg_send_raises`
        TzNot Registered!N)	r�rFr��MSG_DELETE_REQUESTrCr�r�r
r�)rwrr^r�r��flagsrHr�r=r=rA�delete_opaque_data^s z#OspfOpaqueClient.delete_opaque_datac
�s8|j4IdH�|jj|i�j|�dk	SQIdHRXdS)aXDetermine if an (lsa_type, otype) tuple has been registered with FRR

        This determines if the type has been registered, but not necessarily if it is
        ready, if that is required use the `wait_opaque_ready` metheod.

        Args:
            lsa_type: LSA_TYPE_OPAQUE_{LINK,AREA,AS}
            otype: (octet) opaque type.
        N)r�r�rF)rwr^r�r=r=rA�
is_registeredss
zOspfOpaqueClient.is_registeredNc�sr|j||�IdHstd��|r0||j||f<n,||f|jkr\tjdt|�|�|j||f=|j||�IdHdS)a�Register intent to advertise opaque data.

        The application should wait for the async notificaiton that the server is
        ready to advertise the given opaque data type. The API currently only allows
        a single "owner" of each unique (lsa_type,otype). To wait call `wait_opaque_ready`

        Args:
            lsa_type: LSA_TYPE_OPAQUE_{LINK,AREA,AS}
            otype: (octet) opaque type.
            callback: if given, callback will be called when changes are received for
                LSA of the given (lsa_type, otype). The callbacks signature is:

                `callback(msg_type, ifaddr, area_id, lsa_header, data, lsa)`

                Args:
                    msg_type: MSG_LSA_UPDATE_NOTIFY or MSG_LSA_DELETE_NOTIFY
                    ifaddr: integer identifying an interface (by IP address)
                    area_id: integer identifying an area
                    lsa_header: the LSA header as an unpacked tuple (fmt: ">HBBIILHH")
                    data: the opaque data that follows the LSA header
                    lsa: the octets of the full lsa
        Raises:
            See `msg_send_raises`
        NzRegistering registered typez=OSPFCLIENT: register: removing callback for %s opaque-type %s)rr�r�r�r�r`r�)rwr^r��callbackr=r=rA�register_opaque_data�sz%OspfOpaqueClient.register_opaque_datac�s�|j4IdH�d|j|j|�}|dkr,dS|js6t�tjdt|�|�|s^g}|j||<t�}|j	|�WdQIdHRX|j
�IdHtjdt|�|�dS)NTz#waiting for ready %s opaque-type %szREADY for %s opaque-type %s)r�r�rFr�r�r�r�r`r�append�wait)rwr^r�r�rr=r=rA�wait_opaque_ready�s
z"OspfOpaqueClient.wait_opaque_readyc�s*|j|||�IdH|j||�IdHdS)a�Register intent to advertise opaque data and wait for ready.

        The API currently only allows a single "owner" of each unique (lsa_type,otype).

        Args:
            lsa_type: LSA_TYPE_OPAQUE_{LINK,AREA,AS}
            otype: (octet) opaque type.
            callback: if given, callback will be called when changes are received for
                LSA of the given (lsa_type, otype). The callbacks signature is:

                `callback(msg_type, ifaddr, area_id, lsa_header, data, lsa)`

                Args:
                    msg_type: MSG_LSA_UPDATE_NOTIFY or MSG_LSA_DELETE_NOTIFY
                    ifaddr: integer identifying an interface (by IP address)
                    area_id: integer identifying an area
                    lsa_header: the LSA header as an unpacked tuple (fmt: ">HBBIILHH")
                    data: the opaque data that follows the LSA header
                    lsa: the octets of the full lsa
        Raises:

            See `msg_send_raises`
        N)rr)rwr^r�rr=r=rA�register_opaque_data_wait�sz*OspfOpaqueClient.register_opaque_data_waitc�s`|j||�IdHstd��||f|jkr4|j||f=t}tjt|||�}|j||�IdHdS)aBUnregister intent to advertise opaque data.

        This will also cause the server to flush/delete all opaque data of
        the given (lsa_type,otype).

        Args:
            lsa_type: LSA_TYPE_OPAQUE_{LINK,AREA,AS}
            otype: (octet) opaque type.
        Raises:
            See `msg_send_raises`
        NzUnregistering unregistered type)rr�r��MSG_UNREGISTER_OPAQUETYPErCr�r�r�)rwr^r�rHr�r=r=rA�unregister_opaque_data�sz'OspfOpaqueClient.unregister_opaque_datac�s||_|j�IdHdS)a�Monitor changes to LSAs.

        Args:
            callback: if given, callback will be called when changes are received for
                any LSA. The callback signature is:

                `callback(msg_type, ifaddr, area_id, lsa_header, extra, lsa)`

                Args:
                    msg_type: MSG_LSA_UPDATE_NOTIFY or MSG_LSA_DELETE_NOTIFY
                    ifaddr: integer identifying an interface (by IP address)
                    area_id: integer identifying an area
                    lsa_header: the LSA header as an unpacked tuple (fmt: ">HBBIILHH")
                    extra: the octets that follow the LSA header
                    lsa: the octets of the full lsa
        N)r�r�)rwrr=r=rA�monitor_lsa�szOspfOpaqueClient.monitor_lsac�s||_|j�IdHdS)a*Monitor the set of reachable routers.

        The property `reachable_routers` contains the set() of reachable router IDs
        as integers. This set is updated prior to calling the `callback`

        Args:
            callback: callback will be called when the set of reachable
                routers changes. The callback signature is:

                `callback(added, removed)`

                Args:
                    added: list of integer router IDs being added
                    removed: list of integer router IDs being removed
        N)r�r�)rwrr=r=rA�monitor_reachablesz"OspfOpaqueClient.monitor_reachablec�s||_|j�IdHdS)a�Monitor the state of OSPF enabled interfaces.

        Args:
            callback: callback will be called when an interface changes state.
                The callback signature is:

                `callback(ifaddr, area_id, state)`

                Args:
                    ifaddr: integer identifying an interface (by IP address)
                    area_id: integer identifying an area
                    state: ISM_*
        N)r�r�)rwrr=r=rA�monitor_ismszOspfOpaqueClient.monitor_ismc�s||_|j�IdHdS)aMonitor the state of OSPF neighbors.

        Args:
            callback: callback will be called when a neighbor changes state.
                The callback signature is:

                `callback(ifaddr, nbr_addr, router_id, state)`

                Args:
                    ifaddr: integer identifying an interface (by IP address)
                    nbr_addr: integer identifying neighbor by IP address
                    router_id: integer identifying neighbor router ID
                    state: NSM_*
        N)r�r�)rwrr=r=rA�monitor_nsm(szOspfOpaqueClient.monitor_nsmc�s||_|j�IdHdS)a�Monitor the OSPF router ID.

        The property `router_id` contains the OSPF urouter ID.
        This value is updated prior to calling the `callback`

        Args:
            callback: callback will be called when the router ID changes.
                The callback signature is:

                `callback(new_router_id, old_router_id)`

                Args:
                    new_router_id: the new router ID
                    old_router_id: the old router ID
        N)r�r�)rwrr=r=rA�monitor_router_id:sz"OspfOpaqueClient.monitor_router_id)r�F)r)N)N)N)N)N)N)N)rNrOrPr|r�r�r�r�r�rr�r�r�r�r�r�r�rrrrrrrrrrr r!�
__classcell__r=r=)r�rAr�2s2)	 
(#

)




r�ccs<|rx2|D]
}|Vq
Wnxtd�}|s*P|j�VqWdS)z"Get next action from list or STDINrN)�input�strip)Zaction_list�actionr=r=rA�next_actionQs
r&c�s@t|j�}|j�IdH�y�tjddkr:tj|j��ntj�j|j��|j	�IdH|j
�IdH|j�IdH|j�IdH�x t
|j�D�]}|jd�}|jd�}|j�dkr�t|jd��}tjd|�tj|�IdHtjd|�q�t|jd��}|dk�rtd	�}n:|jd�}ytt|��}Wntk
�rJt|�}YnX||t|jd��t|jd��g}	|j|	d|	d
�IdH�s�|j|	d|	d
�IdH|j�dk�r:ytj|jd��}
Wntk
�r�d}
YnXtjd
t|
��t|
�d}|�r"|
dd|7}
tjdt|
��|j|	|
f��IdHq�|j�jd��sNt �d	}t|�dk�r�yt|jd��}Wntk
�r�d	}YnX|j!|	|f��IdHq�W|j�s�|j"�r�d	SWn2t#k
�r�}
ztj$d|
dd�d
Sd}
~
XnXy&tjd�xtjd�IdH�qWWn t%k
�r:tjd�d
SXdS)Nrr
�,Frzwaiting %s secondszwait complete: %s secondsrrr�addr�zopaque data is %s octetsrr�zopaque padding to %s octets�delz async_main: unexpected error: %sT)�exc_infozSleeping forever�xz3Got EOF from OSPF API server on async notify socket)&r�rr��sys�version_infor�Zcreate_taskr�r�r�r�r�r�r&�actions�split�pop�casefoldr
r�r�Zsleepr��
ValueErrorrr�bytes�fromhex�
IndexErrorr�r�
startswithr�r�exitr�r�r�)ry�cr%r�ZwhatZstimeZltyperZavalZoargs�b�mod�fr�r=r=rA�
async_main^sz





 



r<cGsDtj|�}|jdddd�|jdddd�|jd	d
dd�|jdd
ddd�|jdddd�|j�}|jrptjntj}tj|dj	|j
�d�tjd�d}yHtj
ddkr�tjt|��}n&tj�}z|jt|��}Wd|j�XWnRtk
�rtjd�Yn>tk
�r4}ztjd|dd�WYdd}~XnXtjd�|S)Nz--logtagZCLIENTztag to identify log messages)�default�helpz--exit�
store_truezExit after commands)r%r>z--serverr�zOSPF API serverz-vz	--verbosez
be verboser.�*z?WAIT,SEC|(ADD|DEL),LSATYPE,[ADDR,],OTYPE,OID,[HEXDATA|DEL_FLAG])�nargsr>z3%(asctime)s %(levelname)s: {}: %(name)s %(message)s)�levelr~zospfclient: startingrrr
z+Exiting, received KeyboardInterrupt in mainz Exiting, unexpected exception %sT)r*zospfclient: clean exit)�argparse�ArgumentParser�add_argument�
parse_args�verboser��DEBUG�INFOZbasicConfigr~Zlogtagr�r,r-r�Zrunr<r�Zrun_until_completer��KeyboardInterruptr�)ryZaprBZstatusr�r�r=r=rA�main�s<

"
rK�__main__)rr)rr)rr)rr)rr)rr)rr)r$r%)r&r')r)r)r*r+)r,r()r-r.)r/r0)r1r+r�������������i����i����i����i����i����)N)nrCr�r�r�r�rCr,rrZ	ipaddressrr�r�rDr�r�ZLSAF_ORIGIN_NON_SELFZLSAF_ORIGIN_SELFr�r�r�r�rr�r�rrrrrrZ	smsg_infoZOSPF_API_DEL_ZERO_LEN_LSAr�r�r�r�r�r�r�r�r�r�r�r2r3r4r5r6r7r8r9r:r;r<rJZmsg_infor�itemsrEr�r�rIrLr�rMrQrRZLSA_TYPE_UNKNOWNrSrTrUrVrWrXrYrZr[r\r]r`rarbrcrdrerfrgrhrjrkrlrmrnrorprqrrrsrtrurvr}r�r&r<rKrNZexit_statusr7r=r=r=rA�<module>s



	##

L,


MMCT - 2023