o
    )nd|E                     @   s  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
ddlmZ ddlmZmZmZmZ dZdZdZdadZdZd	Zd
Zdd Zdd ZdedefddZdedefddZ dede!fddZ"dede!fddZ#edede$dededef
d d!Z%edededed"ede&f
d#d$Z'ed2de$d"ed(e$d)e$d*ededed+e$de&fd,d-Z(ed3de$d.ed/e&fd0d1Z)dS )4    N   )errors)ICMP_DEFAULT_CODEIcmpTypeIcmpTimeExceededCodeIcmpDestinationUnreachableCodez4.0.4Fz!BBHHHBBHIIz!BBHHHz!d   c                  O   s<   dd }t sdS tp| addd | D }t| dS )zPrint debug info to stdout if `ping3.DEBUG` is True.

    Args:
        *args: Any. Usually are strings or objects that can be converted to str.
    c                  S   sl   t t} | t j t d}t  }|t j || | | | 	d
t | 	d
|  | S )Nz[%(levelname)s] %(message)szPing3 Version: {}z
LOGGER: {})logging	getLogger__name__setLevelDEBUG	FormatterStreamHandlersetFormatter
addHandlerdebugformat__version__)logger	formattercout_handler r   L/var/www/html/api/v1/lib/venv/lib/python3.10/site-packages/ping3/__init__.py
get_logger#   s   



z_debug.<locals>.get_loggerN c                 s       | ]}t |V  qd S Nstr).0itemr   r   r   	<genexpr>3       z_debug.<locals>.<genexpr>)r   LOGGERjoinr   )argskwargsr   messager   r   r   _debug   s   
r)   c                 C   s   t r| dS )zRaise exception if `ping3.EXCEPTIONS` is True.

    Args:
        err: Exception.

    Raise:
        Exception: Exception passed in args will be raised if `ping3.EXCEPTIONS` is True.
    N)
EXCEPTIONS)errr   r   r   _raise7   s   	r,   funcreturnc                    s   t   fdd}|S )zDecorator that log function calls for debug

    Args:
        func: Function to be decorated.

    Returns:
        Decorated function.
    c                     s|   d dd | D }|rt|nd}|r|rd ||fn|p |}tddj| d  | i |}tdd	j |d
 |S )Nz, c                 s   r   r   r   )r    argr   r   r   r"   O   r#   z0_func_logger.<locals>.wrapper.<locals>.<genexpr> zFunction called:z{func.__name__}({})r-   zFunction returned:z{func.__name__} -> {rtrn})r-   rtrn)r%   r   r)   r   )r&   r'   pargskargsall_argsfunc_returnr1   r   r   wrapperM   s   z_func_logger.<locals>.wrapper)	functoolswraps)r-   r7   r   r1   r   _func_loggerD   s   		r:   sourcec                 C   sh   d}d|> }t | ddd t | ddd |d >  }||kr+t t||}||ks | d|> d @ S )zCalculates the checksum of the input bytes.

    RFC1071: https://tools.ietf.org/html/rfc1071
    RFC792: https://tools.ietf.org/html/rfc792

    Args:
        source: Bytes. The input to be calculated.

    Returns:
        int: Calculated checksum.
       r   N   )sumdivmod)r;   BITScarryresultr   r   r   checksumZ   s   ,rC   rawc                 C   s   d}t t|tt| S )zGet information from raw ICMP header data.

    Args:
        raw: Bytes. Raw data of ICMP header.

    Returns:
        A map contains the infos from the raw header.
    )typecoderC   idseq)dictzipstructunpackICMP_HEADER_FORMAT)rD   icmp_header_keysr   r   r   read_icmp_headern   s   	rO   c                 C   sP   dt dtfdd}d}tt|tt| }||d |d< ||d |d< |S )zGet information from raw IP header data.

    Args:
        raw: Bytes. Raw data of IP header.

    Returns:
        A map contains the infos from the raw header.
    ipr.   c                    s   d  fdddD S )N.c                 3   s     | ]}t  |? d @ V  qdS )   Nr   )r    offsetrP   r   r   r"      s    z7read_ip_header.<locals>.stringify_ip.<locals>.<genexpr>)   r<      r   )r%   rT   r   rT   r   stringify_ip   s   z$read_ip_header.<locals>.stringify_ip)
versiontoslenrG   flagsttlprotocolrC   src_addr	dest_addrr^   r_   )intr   rI   rJ   rK   rL   IP_HEADER_FORMAT)rD   rW   ip_header_keys	ip_headerr   r   r   read_ip_header{   s   	rd   sockr_   icmp_idrH   sizec              
   C   s   t d| zt|}W n tjy" } ztj|d|d}~ww t d| d}tt	t
jt|||}|tt d }ttt |  }	t||	 }
tt	t
jtt|
||}t dt| t d|	 ||	 }| ||df dS )	a  Sends one ping to the given destination.

    ICMP Header (bits): type (8), code (8), checksum (16), id (16), sequence (16)
    ICMP Payload: time (double), data
    ICMP Wikipedia: https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol

    Args:
        sock: Socket.
        dest_addr: The destination address, can be an IP address or a domain name. Ex. "192.168.1.1"/"example.com"
        icmp_id: ICMP packet id. Calculated from Process ID and Thread ID.
        seq: ICMP packet sequence, usually increases from 0 in the same process.
        size: The ICMP packet payload size in bytes. Note this is only for the payload part.

    Raises:
        HostUnkown: If destination address is a domain name and cannot resolved.
    zDestination address: '{}')r_   NzDestination IP address:r   QzSent ICMP header:zSent ICMP payload:)r)   r   socketgethostbynamegaierrorr   HostUnknownrK   packrM   r   ECHO_REQUESTr   calcsizeICMP_TIME_FORMATtimeencoderC   htonsrO   sendto)re   r_   rf   rH   rg   r+   pseudo_checksumicmp_headerpaddingicmp_payloadreal_checksumpacketr   r   r   send_one_ping   s$   

r{   timeoutc                 C   s  t jdkpt dkp| jtjk}|r(tdt	t
}t|j|jt	t }ntd tdt	t}t | }tdt|| 	 |t  }|dkrR|nd}td| t| gg g |}	|	d g krptj|dt }
td	t|
|
 | d
\}}|r|| }t|}td| nd}|| ||jd }}t|}td| td| |s|  d }|d tjkr|d tjkrtj||dt |d tjkr|d tj krtj!||dtj"||d|d r?|d tj#krtd qE|d |krtd qE|d |krtd qE|d tj$kr?t%t&|dt	t& d }tdt|| |
| S td| qF)a}  Receives the ping from the socket.

    IP Header (bits): version (8), type of service (8), length (16), id (16), flags (16), time to live (8), protocol (8), checksum (16), source ip (32), destination ip (32).
    ICMP Packet (bytes): IP Header (20), ICMP Header (8), ICMP Payload (*).
    Ping Wikipedia: https://en.wikipedia.org/wiki/Ping_(networking_utility)
    ToS (Type of Service) in IP header for ICMP is 0. Protocol in IP header for ICMP is 1.

    Args:
        sock: The same socket used for send the ping.
        icmp_id: ICMP packet id. Sent packet id should be identical with received packet id.
        seq: ICMP packet sequence. Sent packet sequence should be identical with received packet sequence.
        timeout: Timeout in seconds.

    Returns:
        The delay in seconds or None on timeout.

    Raises:
        TimeToLiveExpired: If the Time-To-Live in IP Header is not large enough for destination.
        TimeExceeded: If time exceeded but Time-To-Live does not expired.
        DestinationHostUnreachable: If the destination host is unreachable.
        DestinationUnreachable: If the destination is unreachable.
    posixDarwinr   zUnprivileged on LinuxzTimeout time: {} ({})TzTimeout left: {:.2f}s)r|   zReceived time: {} ({}))i  zReceived IP header:NzReceived ICMP header:zReceived ICMP payload:r   rE   rF   )rc   rv   rG   z+ECHO_REQUEST received. Packet filtered out.z&ICMP ID dismatch. Packet filtered out.rH   z'IMCP SEQ dismatch. Packet filtered out.zReceived sent time: {} ({})zUncatched ICMP packet:)'osnameplatformsystemrE   ri   SOCK_RAWslicerK   ro   ra   stoprM   r)   rq   r   ctimeselectr   Timeoutrecvfromrd   rO   getsocknamer   TIME_EXCEEDEDr   TTL_EXPIREDTimeToLiveExpiredTimeExceededDESTINATION_UNREACHABLEr   DESTINATION_HOST_UNREACHABLEDestinationHostUnreachableDestinationUnreachablern   
ECHO_REPLYrL   rp   )re   rf   rH   r|   has_ip_headerip_header_sliceicmp_header_slicetimeout_timetimeout_leftselected	time_recv	recv_dataaddrip_header_rawrc   icmp_header_rawicmp_payload_rawrv   	time_sentr   r   r   receive_one_ping   sj   "



r      s8   unitr^   r\   	interfacec                 C   s  zt  t jt jt j}W n, ty8 }	 z |	jtjkr,td|	 t  t jt j	t j}n|	W Y d}	~	nd}	~	ww | |rz|
t jt jrQ|t jt j| W n tyk }	 ztd|	 W Y d}	~	nd}	~	ww z|
t jt jr~|t jt j| W n ty }	 ztd|	 W Y d}	~	nd}	~	ww |r|t jt|  td| |r||df td| ttdrt nt j}
t }td	||
 d
@ }zt|| |||d t||||d}W nE tj y }	 zt|	 t!|	 W Y d}	~	W d   dS d}	~	w tj"y/ }	 zt|	 t!|	 W Y d}	~	W d   dS d}	~	ww |du r>	 W d   dS |dkrG|d9 }|W  d   S 1 sTw   Y  dS )ag  
    Send one ping to destination address with the given timeout.

    Args:
        dest_addr: The destination address, can be an IP address or a domain name. Ex. "192.168.1.1"/"example.com"
        timeout: Time to wait for a response, in seconds. Default is 4s, same as Windows CMD. (default 4)
        unit: The unit of returned value. "s" for seconds, "ms" for milliseconds. (default "s")
        src_addr: The IP address to ping from. This is for multiple network interfaces. Ex. "192.168.1.20". (default None)
        interface: LINUX ONLY. The gateway network interface to ping from. Ex. "wlan0". (default None)
        ttl: The Time-To-Live of the outgoing packet. Default is None, which means using OS default ttl -- 64 onLinux and macOS, and 128 on Windows. (default None)
        seq: ICMP packet sequence, usually increases from 0 in the same process. (default 0)
        size: The ICMP packet payload size in bytes. If the input of this is less than the bytes of a double format (usually 8), the size of ICMP packet payload is 8 bytes to hold a time. The max should be the router_MTU(Usually 1480) - IP_Header(20) - ICMP_Header(8). Default is 56, same as in macOS. (default 56)

    Returns:
        The delay in seconds/milliseconds, False on error and None on timeout.

    Raises:
        PingError: Any PingError will raise again if `ping3.EXCEPTIONS` is True.
    zB`{}` when create socket.SOCK_RAW, using socket.SOCK_DGRAM instead.Nz5Set Socket Option `IP_TTL` in `IPPROTO_IP` Failed: {}z1Set Socket Option `IP_TTL` in `SOL_IP` Failed: {}zSocket Interface Binded:r   zSocket Source Address Binded:get_native_idz{}{}i  )re   r_   rf   rH   rg   )re   rf   rH   r|   Fmsi  )#ri   AF_INETr   IPPROTO_ICMPPermissionErrorerrnoEPERMr)   r   
SOCK_DGRAM
getsockopt
IPPROTO_IPIP_TTL
setsockoptOSErrorSOL_IP
SOL_SOCKETSOCKET_SO_BINDTODEVICErr   bindhasattr	threadingr   currentThreadidentr   getpidzlibcrc32r{   r   r   r   r,   	PingError)r_   r|   r   r^   r\   rH   rg   r   re   r+   	thread_id
process_idrf   delayr   r   r   ping  sx   





"&r   countintervalc                 O   s  | d}| d}|dd}d}||k s|dkr|dkr'|dkr't| d| }	|	|r4d|nd7 }	|	d	7 }	t| g|R d
|i|}
t|	dd |
du r^t|rZd|nd n|
du rgtd ntdjt|
|d |d7 }||k s|dksdS dS )ag  
    Send pings to destination address with the given timeout and display the result.

    Args:
        dest_addr: The destination address. Ex. "192.168.1.1"/"example.com"
        count: How many pings should be sent. 0 means infinite loops until manually stopped. Default is 4, same as Windows CMD. (default 4)
        interval: How many seconds between two packets. Default is 0, which means send the next packet as soon as the previous one responsed. (default 0)
        *args and **kwargs: And all the other arguments available in ping() except `seq`.

    Returns:
        Formatted ping results printed.
    r|   r^   r   r   r   z	ping '{}'z
 from '{}'r0   z ... rH   )endNzTimeout > {}sr   FErrorz{value}{unit})valuer   r   )get
setdefaultrq   sleepr   r   printr`   )r_   r   r   r&   r'   r|   srcr   ioutput_textr   r   r   r   verbose_pingG  s&   




r   )r   r   NNr   r   N)r   r   )*r   ri   rK   r   rq   r   r   r   r	   r8   r   r0   r   enumsr   r   r   r   r   r   r*   r$   ra   rM   rp   r   r)   r,   callabler:   bytesr`   rC   rI   rO   rd   r   r{   floatr   r   r   r   r   r   r   <module>   sF    $ O2C