HEX
Server: Apache
System: Linux box5154.bluehost.com 5.14.0-162.23.1.9991722448259.nf.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Jul 31 18:11:45 UTC 2024 x86_64
User: almiraso (1849)
PHP: 8.2.31
Disabled: NONE
Upload Files
File: //lib64/python3.9/site-packages/ntp/__pycache__/packet.cpython-39.pyc
a

\��dk�@s�dZddlmZmZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlZddl
Z
ddlZddlZddlZddlZddlZdZdZdZdZdZd	Zd
ZdZdZGd
d�d�ZGdd�de�ZGdd�de�Z Gdd�de�Z!Gdd�d�Z"dZ#dZ$dZ%dZ&dZ'dZ(dZ)dZ*dZ+d Z,d!Z-d"Z.d#Z/d$Z0d%Z1d&Z2d'Z3d(Z4d)Z5d*Z6d+Z7d,Z8d-Z9d.Z:d/Z;ej<fd0d1�Z=Gd2d3�d3�Z>Gd4d5�d5�Z?Gd6d7�d7e�Z@Gd8d9�d9�ZAd:d;�ZBd<d=�ZCd>d?�ZDd@dA�ZEdBdC�ZFGdDdE�dE�ZGdS)Fa(
packet.py - definitions and classes for Python querying of NTP

Freely translated from the old C ntpq code by ESR, with comments
preserved.  The idea was to cleanly separate ntpq-that-was into a
thin front-end layer handling mainly command interpretation and a
back-end that presents the take from ntpd as objects that can be
re-used by other front ends. Other reusable pieces live in util.py.

This code should be Python2-vs-Python-3 agnostic.  Keep it that way!

Here are some pictures to help make sense of this code. First, from RFC 5905,
the general structure of an NTP packet (Figure 8):

       0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |LI | VN  |Mode |    Stratum    |     Poll      |  Precision    |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                         Root Delay                            |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                         Root Dispersion                       |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                          Reference ID                         |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                                                               |
      +                     Reference Timestamp (64)                  +
      |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                                                               |
      +                      Origin Timestamp (64)                    +
      |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                                                               |
      +                      Receive Timestamp (64)                   +
      |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                                                               |
      +                      Transmit Timestamp (64)                  +
      |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                                                               |
      .                                                               .
      .                    Extension Field 1 (variable)               .
      .                                                               .
      |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                                                               |
      .                                                               .
      .                    Extension Field 2 (variable)               .
      .                                                               .
      |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                          Key Identifier                       |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                                                               |
      |                           digest (128)                        |
      |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

The fixed header is 48 bytes long.  The simplest possible case of an
NTP packet is the minimal SNTP request, a mode 3 packet with the
Stratum and all following fields zeroed out to byte 47.

How to interpret these fields:

The modes are as follows:

+-------+--------------------------+
| Value | Meaning                  |
+-------+--------------------------+
| 0     | reserved                 |
| 1     | symmetric active         |
| 2     | symmetric passive        |
| 3     | client                   |
| 4     | server                   |
| 5     | broadcast                |
| 6     | NTP control message      |
| 7     | reserved for private use |
+-------+--------------------------+

While the Stratum field has 8 bytes, only values 0-16 (low 5 bits)
are legal. Value 16 means 'unsynchronized' Values 17-255 are reserved.

LI (Leap Indicator), Version, Poll, and Precision are not described
here; see RFC 5905.

t_1, the origin timestamp, is the time according to the client at
which the request was sent.

t_2, the receive timestamp, is the time according to the server at
which the request was received.

t_3, the transmit timestamp, is the time according to the server at
which the reply was sent.

You also need t_4, the destination timestamp, which is the time according to
the client at which the reply was received.  This is not in the reply packet,
it's the packet receipt time collected by the client.

The 'Reference timestamp' is an unused historical relic.  It's supposed to be
copied unchanged from upstream in the stratum hierarchy. Normal practice
has been for Stratum 1 servers to fill it in with the raw timestamp from the
most recent reference-clock.

Theta is the thing we want to estimate: the offset between the server
clock and the client clock. The sign convention is that theta is
positive if the server is ahead of the client.

Theta is estimated by [(t_2-t_1)+(t_3-t_4)]/2. The accuracy of this
estimate is predicated upon network latency being symmetrical.

Delta is the network round trip time, i.e. (t_4-t_1)-(t_3-t_2). Here's
how the terms work: (t_4-t_1) is the total time that the request was
in flight, and (t_3-t_2) is the time that the server spent processing it;
when you subtract that out you're left with just network delays.

Lambda nominally represents the maximum amount by which theta could be
off. It's computed as delta/2 + epsilon. The delta/2 term usually
dominates and represents the maximum amount by which network asymmetry
could be throwing off the calculation. Epsilon is the sum of three
other sources of error:

rho_r: the (im)precision field from response packet, representing the
server's inherent error in clock measurement.

rho_s: the client's own (im)precision.

PHI*(t_4-t_1): The amount by which the client's clock may plausibly
have drifted while the packet was in flight. PHI is taken to be a
constant of 15ppm.

rho_r and rho_s are estimated by making back-to-back calls to
clock_gettime() (or similar) and taking their difference. They're
encoded on the wire as an eight-bit two's complement integer
representing, to the nearest integer, log_2 of the value in seconds.

If you look at the raw data, there are 3 unknowns:
   * transit time client to server
   * transit time server to client
   * clock offset
but there are only two equations, so you can't solve it.

NTP gets the 3rd equation by assuming the transit times are equal.  That lets
it solve for the clock offset.

If you assume that both clocks are accurate which is reasonable if you have
GPS at both ends, then you can easily solve for the transit times in each
direction.

The RFC 5905 diagram is slightly out of date in that the digest header assumes
a 128-bit (16-octet) MD5 hash, but it is also possible for the field to be a
128-bit AES_CMAC hash or 160-bit (20-octet) SHA-1 hash.  NTPsec will
support any 128- or 160-bit MAC type in libcrypto.

An extension field consists of a 16-bit network-order type field
length, followed by a 16-bit network-order payload length in octets,
followed by the payload (which must be padded to a 4-octet boundary).

       0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |         Type field             |      Payload length          |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                                                               |
      |                        Payload (variable)                     |
      |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Here's what a Mode 6 packet looks like:

       0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |LI | VN  | 6   |R|E|M|  Opcode  |          Sequence            |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |               Status           |       Association ID         |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |               Offset           |            Count             |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                                                               |
      .                                                               .
      .                        Payload (variable)                     .
      .                                                               .
      |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                          Key Identifier                       |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                                                               |
      |                           digest (128)                        |
      |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

In this case, the fixed header is 24 bytes long.

R = Response bit
E = Error bit
M = More bit.

A Mode 6 packet cannot have extension fields.

�)�print_function�divisionN� i�i�i�������c@sreZdZdZedd��Zedd��Zejj	ejj
dfdd�Zed	d
��Z
e
jdd
��Z
dd
�Zdd�Zdd�ZdS)�PacketzEncapsulate an NTP fragmentcCs|d@d>|d@BS)N���)�v�mr
r
�0/usr/lib64/python3.9/site-packages/ntp/packet.py�VN_MODEszPacket.VN_MODEcCs|d@d>t�||�BS)Nr�)r
r)�lrrr
r
r�PKT_LI_VN_MODEszPacket.PKT_LI_VN_MODENcCs*||_d|_d|_t�tjj||�|_dS)Nr�)�session�
li_vn_mode�	extensionr
r�ntp�magicZLEAP_NOTINSYNC)�self�mode�versionrr
r
r�__init__s
�zPacket.__init__cCs|jS�N)�_Packet__extension�rr
r
rrszPacket.extensioncCstj�|�|_dSr)r�poly�	polybytesr )r�xr
r
rr"scCsdtj�|j�S)N)zno-leapzadd-leapzdel-leapZunsync)rrZPKT_LEAPrr!r
r
r�leap&s�zPacket.leapcCs|jd?d@S)Nrr�rr!r
r
rr*szPacket.versioncCs
|jd@S)Nrr&r!r
r
rr-szPacket.mode)�__name__�
__module__�__qualname__�__doc__�staticmethodrrrrZMODE_CLIENT�NTP_VERSIONr�propertyr�setterr%rrr
r
r
rr
	s

�



r
c@seZdZddd�Zdd�ZdS)�
SyncExceptionrcCs||_||_dSr��message�	errorcode�rr1r2r
r
rr2szSyncException.__init__cCs|jSr�r1r!r
r
r�__str__6szSyncException.__str__N)r�r'r(r)rr5r
r
r
rr/1s
r/c@s�eZdZdZdZdZdZdZd2dd�Zd	d
�Z	e
dd��Ze
d
d��Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd �Zd!d"�Zd#d$�Zd%d&�Zd'd(�Zd)d*�Zd+d,�Zd-d.�Zd/d0�Zd1S)3�
SyncPacketz5Mode 1-5 time-synchronization packet, including SNTP.z!BBBbIIIQQQQ�0l�~TghUMu�>�cCs�t�|�d|_d|_d|_d|_d|_d|_d|_d|_	d|_
d|_d|_d|_
g|_d|_d|_d|_t�t���|_d|_d|_|r�|�tj�|��dS)Nrr9TF)r
r�status�stratum�poll�	precision�
root_delay�root_dispersion�refid�reference_timestamp�origin_timestamp�receive_timestamp�transmit_timestampr�	extfields�mac�hostnameZresolvedr7�posix_to_ntp�time�receivedZtrusted�rescaled�analyzerr"r#)r�datar
r
rrAs,
zSyncPacket.__init__cCs,t|�}|tjks|d@dkr&td��t�tj|dtj��\|_|_|_	|_
|_|_|_
|_|_|_|_|tjd�|_|j}t|�dkr�t�d|dd��\}}|j�||dd|�f�|d|d�}q�t|�dkr�||_nBt|�dkr�td	��n,t|�d
v�rtd��nt|�dv�r(||_dS)
Nrrzimpossible packet length�z!IIrrrzUnsupported DES authentication)rrzPacket is a runt)r	rN)�lenr7�
HEADER_LENr/�struct�unpack�formatrr;r<r=r>r?r@rArBrCrDrrE�appendrF)rrMZdatalen�payloadZftypeZflenr
r
rrLYs>��

zSyncPacket.analyzecCs|dtjS)z!Scale from NTP time to POSIX time�)r7�
UNIX_EPOCH��tr
r
r�ntp_to_posix�szSyncPacket.ntp_to_posixcCst|tjd�S)z!Scale from POSIX time to NTP timerV)�intr7rWrXr
r
rrH�szSyncPacket.posix_to_ntpcCsr|jsnd|_|jdL_|jdL_t�|j�|_t�|j�|_t�|j�|_t�|j�|_t�|j	�|_	dS)z%Rescale all timestamps to POSIX time.TrN)
rKr>r?r7rZrArBrCrDrJr!r
r
r�posixize�s"����zSyncPacket.posixizecCs|jSr)rBr!r
r
r�t1�sz
SyncPacket.t1cCs|jSr)rCr!r
r
r�t2�sz
SyncPacket.t2cCs|jSr)rDr!r
r
r�t3�sz
SyncPacket.t3cCs|jSr)rJr!r
r
r�t4�sz
SyncPacket.t4cCs |��|��|��|��S)zPacket flight time)r`r]r_r^r!r
r
r�delta�szSyncPacket.deltacCs tj|��|��d|jS)z(Residual error due to clock imprecision.�)r7�PHIr`r]r=r!r
r
r�epsilon�szSyncPacket.epsiloncCst|��d|���S)z?Synchronization distance, estimates worst-case error in secondsrb)�absrardr!r
r
r�synchd�szSyncPacket.synchdcCs$|��|��|��|��dS)z9Adjustment implied by this packet - 'theta' in NTP-speak.rb)r^r]r_r`r!r
r
r�adjust�szSyncPacket.adjustcCsBt�tj|j|j|j|j|j|j	|j
|j|j|j
|j�}||jS�z*Flatten the packet into an octet sequence.)rQ�packr7rSrr;r<r=r>r?r@rArBrCrDr�r�bodyr
r
r�flatten�s�zSyncPacket.flattencCs0|jd?d@|jd?d@|jd?d@|jd@fS)zAnalyze refid into octets.rN�rr)r@r!r
r
r�refid_octets�s
�zSyncPacket.refid_octetscCstj�tjd|����S)z'Sometimes it's a clock name or KOD type)ZBBBB)rr"�polystrrQrirnr!r
r
r�refid_as_string�szSyncPacket.refid_as_stringcCstj�d|���S)zSometimes it's an IPV4 address.z%d.%d.%d.%d)rr"rornr!r
r
r�refid_as_address�szSyncPacket.refid_as_addresscCst|j�dkS)Nr�rOrFr!r
r
r�
is_crypto_nak�szSyncPacket.is_crypto_nakcCst|j�dkS)Nr	rrr!r
r
r�has_MD5�szSyncPacket.has_MD5cCst|j�dkS)NrNrrr!r
r
r�has_SHA1�szSyncPacket.has_SHA1cCsd|��|��|��f}|d|j|jf7}|��}tdd�|D��sP|��}|d|7}|dtj	�
t�|j
��7}|dtj	�
t�|j��7}|dtj	�
t�|j��7}|dtj	�
t�|j��7}|jr�|dt|j�7}|j�r|dt|j�dd�7}|d7}|S)	z@Represent a posixized sync packet in an eyeball-friendly format.z<NTP:%s:%d:%d:z%f:%fcss|]}|tjvVqdSr)�stringZ	printable)�.0�cr
r
r�	<genexpr>�rz&SyncPacket.__repr__.<locals>.<genexpr>�:�����>)r%rrr>r?rp�allrqr�utilZrfc3339r7rZrArBrCrDrE�reprrF)r�r�rsr
r
r�__repr__�s0

�

�

�

�zSyncPacket.__repr__N)r9)r'r(r)r*rSrPrWrcrrLr+rZrHr\r]r^r_r`rardrfrgrlrnrprqrsrtrur�r
r
r
rr7:s8
)

r7c@sreZdZdZddd�ZdZdZdd	�Zd
d�Zdd
�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�ZdS)�
ControlPacketzMode 6 request/response.rr9cCsJtj|tjj|j|d�||_d|_d|_||_	d|_
||_t|�|_
dS)N)rrrr{r)r
rrr�MODE_CONTROL�
pktversion�r_e_m_op�sequencer:�associd�offsetrrO�count)rr�opcoder��qdatar
r
rrs�zControlPacket.__init__z!BBHHHHHrcCs|jd@rdSdS)N�TF�r�r!r
r
r�is_responseszControlPacket.is_responsecCs|jd@rdSdS)N�@TFr�r!r
r
r�is_errorszControlPacket.is_errorcCs|jd@rdSdS)NrTFr�r!r
r
r�moreszControlPacket.morecCs
|jd@S)N�r�r!r
r
rr�szControlPacket.opcodecCs|jd?d@S)Nrrm)r:r!r
r
r�errcodeszControlPacket.errcodecCs|j|jSr)r�r�r!r
r
r�endszControlPacket.endcCsd|j|��|jfS)z Return statistics on a fragment.z%5d %5d	%3d octets
)r�r�r�r!r
r
r�stats szControlPacket.statscCsdtj�|�}t�tj|dtj��\|_|_	|_
|_|_|_
|_|tjd�|_|j
|j|j|j
fSr)rr"r#rQrRr�rSrPrr�r�r:r�r�r�r)r�rawdatar
r
rrL$s��zControlPacket.analyzec
Cs2t�tj|j|j|j|j|j|j	|j
�}||jSrh)rQrir�rSrr�r�r:r�r�r�rrjr
r
rrl1s�zControlPacket.flattencCs|j�|���dSr)r�sendpktrlr!r
r
r�send=szControlPacket.sendN)rrr9)r'r(r)r*rrSrPr�r�r�r�r�r�r�rLrlr�r
r
r
rr��s

r�c@s,eZdZdZdd�Zdd�Zdd�ZeZdS)	�Peerz*The information we have about an NTP peer.cCs||_||_||_i|_dSr)rr�r:�	variables)rrr�r:r
r
rrDsz
Peer.__init__cCs|j��|_dSr)r�readvarr�r!r
r
r�readvarsJsz
Peer.readvarscCsd|j|jfS)Nz<Peer: associd=%s status=%0x>)r�r:r!r
r
rr5MszPeer.__str__N)r'r(r)r*rr�r5r�r
r
r
rr�As
r�z.***Server reports a bad format request packet
z/***Server disallowed request (authentication?)
z****Server reports a bad opcode in request
z(***Association ID {0} unknown to server
z,***A request variable unknown to the server
z/***Server indicates a request variable was bad
z(***Server returned an unspecified error
z.***Socket error; probably ntpd is not running
z***Request timed out
z'***Response from server was incomplete
z****Buffer size exceeded for returned data
z***Select call failed
z***No host open
z3***Response length should have been a multiple of 4z***Invalid key identifierz***Invalid passwordz***Key not foundz#***Unexpected nonce response formatz***Unknown parameter '%s'z***No credentialsz***Server error code %sz?***No response, probably high-traffic server with low MRU limitz***Bad MRU tag %sz#***Sort order %s is not implementedz%***No trusted keys have been declaredcCs�d}|r�tj�||�\}}t|�}d|}dd�|D�}|t|�;}||kr\|d||7}dd�|D�}|d�|�d7}|�|�qd	S)
z.Dump a packet in hex, in a familiar hex formatrz%02x cSsg|]}tj�|��qSr
)rr"�polyord�rwr$r
r
r�
<listcomp>wrz&dump_hex_printable.<locals>.<listcomp>z   cSs0g|](}d|krdkr(nnt|�nd�qS)r��.)�chrr�r
r
rr�|rr9�
N)rr�	slicedatarO�tuple�join�write)�xdataZoutfpZrowsizeZlinedataZlinelen�liner
r
r�dump_hex_printablemsr�c@s0eZdZdZdd�Zdd�Zdd�Zdd	�Zd
S)�MRUEntryz A traffic entry for an MRU list.cCs4d|_d|_d|_d|_d|_d|_d|_d|_dS)Nr)�addr�last�first�mvr��ct�sc�drr!r
r
rr�szMRUEntry.__init__cCs*tj�|j�}tj�|j�}|||jSr)r�ntpc�
lfptofloatr�r�r�)rr�r�r
r
r�avgint�szMRUEntry.avgintcCsx|j}|ddkrP|d|�d��}|�d�}|dkrB|d|�}t�tj|�S|d|�d��}dt�tj|�SdS)Nr�[r{�]�%rzs)r��find�socketZ	inet_ptonZAF_INET6ZAF_INET)rr�Zpctr
r
r�sortaddr�s
zMRUEntry.sortaddrcCsdt|j�dd�dS)Nz<MRUEntry: r{r|r})r��__dict__r!r
r
rr��szMRUEntry.__repr__N)r'r(r)r*rr�r�r�r
r
r
rr��s

r�c@s(eZdZdZdd�Zdd�Zdd�ZdS)	�MRUListzFA sequence of address-timespan pairs returned by ntpd in one response.cCsg|_d|_dSr��entries�nowr!r
r
rr�szMRUList.__init__cCs
|jduS)z2Is the server done shipping entries for this span?N)r�r!r
r
r�is_complete�szMRUList.is_completecCsd|j|jfS)Nz<MRUList: entries=%s now=%s>r�r!r
r
rr��szMRUList.__repr__N)r'r(r)r*rr�r�r
r
r
rr��sr�c@seZdZddd�Zdd�ZdS)�ControlExceptionrcCs||_||_dSrr0r3r
r
rr�szControlException.__init__cCs|jSrr4r!r
r
rr5�szControlException.__str__N)rr6r
r
r
rr��s
r�c@s2eZdZdZdZdZejjdejj	dejj
dejjdejjdejj
d	ejjd
ejjdiZdd
�Zdd�Zdd�Zdd�Zdd�Zejfdd�Zdd�Zdd�Zd>dd�Zdd �Zd!d"�Zd?d%d&�Zd@d'd(�ZdAd)d*�Z d#d+ejj!dfd,d-�Z"d.d/�Z#d0d1�Z$d2d3�Z%d4d5�Z&dBd6d7�Z'd8d9�Z(d:d;�Z)d<d=�Z*d+S)C�ControlSessionzA session to a host�TZUNSPECZ
PERMISSIONZBADFMTZBADOPZBADASSOCZ
UNKNOWNVARZBADVALUEZRESTRICTcCs�d|_tj|_t|_t|_tj	j
d|_d|_d|_
d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_tj|_tj|_d|_d|_d|_ dS)Nrr{FZMD5r9)!�debugr��	AF_UNSPEC�	ai_family�
DEFTIMEOUT�primary_timeout�DEFSTIMEOUT�secondary_timeoutrr�NTP_OLDVERSIONr��always_auth�keytype�keyid�passwd�authrG�isnum�sock�portr��response�rstatusr��
MRU_ROW_LIMIT�ntpd_row_limit�sys�stdout�logfp�
nonce_xmit�slots�flakeyr!r
r
rr�s,zControlSession.__init__cCstj�|j||j|�dSr�rr�dologr�r�)r�textZ	thresholdr
r
r�warndbg�szControlSession.warndbgcCs|jr|j��d|_dSr)r��closer!r
r
rr��s
zControlSession.closecCs
|jduS)z#Is the session connected to a host?N)r�r!r
r
r�havehost�szControlSession.havehostc	
s���d�r�dd����fdd�}z|dtjd�WStjyz}z,tj��jd�|jf�j	d	�WYd
}~n
d
}~00z|ddd�WStj�y�}�z�jd
ur��j�
d�|jf�tj}z|tjO}Wnt
y�Yn0z�ttd
��rtjtjf}ntjf}|j|v�r|z|ddd�WWWYd
}~Stj�yz}z*�jd
u�rf�j�
d|j�WYd
}~n
d
}~00Wn,t
�y��jd
u�r��j�
d�Yn0WYd
}~n
d
}~00d
S)z5Try different ways to interpret an address and familyr�r{r|cst��|�jtjtj|�Sr)r�Zgetaddrinfor�Z
SOCK_DGRAMZIPPROTO_UDP�r��hints��hnamerr
r�
hinted_lookups
�z2ControlSession.__lookuphost.<locals>.hinted_lookuprr�z*ntpq: numeric-mode lookup of %s failed, %srNrz,ntpq: standard-mode lookup of %s failed, %s
�
EAI_NODATAzntpq: ndp lookup failed, %s
z+ntpq: API error, missing socket attributes
)�
startswithr�ZAI_NUMERICHOSTZgaierrorrrr�r��strerrorr�r�ZAI_CANONNAMEZ
AI_ADDRCONFIG�AttributeError�hasattrZ
EAI_NONAMEr��errno)	rr��famr��e�e1Zfallback_hintsZerrlist�e2r
r�rZ__lookuphost�sT

��
�� � zControlSession.__lookuphostc

Cs(|�||�}|durdS|d\}}}}}|durLt�|d|�|_d|_n|pR||_d|_tj�|jd|j|j	d�|d|_
zt�|||�|_Wn<tjy�}	z"t
d||	j|	jf��WYd}	~	n
d}	~	00z|j�|�Wn>tj�y"}	z"t
d	||	j|	jf��WYd}	~	n
d}	~	00dS)
z"openhost - open a socket to a hostNFrTzOpening host %srr{zError opening %s: %s [%d]zError connecting to %s: %s [%d])�_ControlSession__lookuphostr�Z	inet_ntoprGr�rrr�r�r�r�r��errorr�r�r�Zconnect)
rr�r��resZfamilyZsocktypeZprotocolZ	canonnameZsockaddrr�r
r
r�openhost.s4
�
��zControlSession.openhostc	Csd|jdur�|jdur8zt�|_Wnttfy6Yn0|jr�|jdkr�z|j��\|_|_|_WdSt	y~t
t��Yn0z<t�
d�r�ttj�d��}nd}|dks�|tkr�t
t��Wntt	fy�t
t��Yn0||_|jdu�r`z|j|j\|_}WnTttf�yXt�d|j�}|du�r:t
t��t|�dk�rTtj�|�}Yn0||_dS)z2Get a keyid and the password if we don't have one.NZ	localhostrzKeyid: z
%s Password: r	)r�r��
Authenticator�OSError�IOErrorrG�controlr�r��
ValueErrorr��SERR_NOTRUST�os�isattyr[rr"Z	polyinput�	MAX_KEYID�SERR_BADKEY�SyntaxError�
IndexError�	TypeError�getpass�SERR_INVPASSrOr�
hexstr2octets)rZkey_idr�r
r
r�passwordJs@

�

zControlSession.passwordcCs�t|�dr|d7}qtj�|jdt|�|jf|jd�z|j�tj	�
|��Wn2tjy�|jdur~|j�
d|j�YdS0|jdkr�|jdur�|j�
d	�t||j�d
S)zSend a packet to the host.r�zSending %d octets.  seq=%drNzWrite to %s failed
r|�zRequest packet:
r)rOrrr�r�r�r�r�Zsendallr"r#r�r�r�rGr�)rr�r
r
rr�ss$

��
zControlSession.sendpktFcCs�|jdkr@|jdur@|jdkr*|j�d�|j�d|||f�t|�tjjkrr|jdurn|j�dt|��dSt||||�}|jd7_|jd;_|j|_|j	r�tj
�|j	�|_	tjt|j	�d@r�|j	d	7_	q�|s�|j
s�|��S|jdu�s|jdu�rtt��tjt|j	�d
@�r8|j	d	7_	�qt�|��|j|j|j�}|du�rftt��n|j	tj
�|�7_	|��S)z(Ship an ntpq request packet to a server.r{Nrr�z-sendrequest: opcode=%d, associd=%d, qdata=%s
z'***Internal error! Data too large (%d)
r|irr)r�r�r�rOrr��CTL_MAX_DATA_LENr�r�rr"r#rPr�r�r�r�r��SERR_NOCREDr��compute_macrlr��
SERR_NOKEY)rr�r�r�r�ZpktrFr
r
r�sendrequest�sB
�
�

�

zControlSession.sendrequestcsPg}d�_d}d}�jdur&�jj}ndd�}�fdd�}|dd	�|d	7}|d
tkr`tt��|sp�jd}	n
�jd}	|dt�	�|	fd
�zt
�
�jggg|	�\}
}}Wnt
jy�tt
��Yn0|dt�	�|	fd
�|
�sn|s�|r�tt��|�rf�jd	k�rf�jdu�rf�j�d�t|�D]&\}}
�j�d|d	|
��f��q*�j�dd|�tt��|dt�	�d�ztj��j�d��}Wntj�y�tt��Yn0�j�rވjt��k�r�|dd	�d}|dt|�d�t���z��|�Wntj�y$tt��Yn0�� �|||�}|�s>qD�j!�r��j"�r��j#t$}||t%7}t|�|t&t'k�r��j�dt|�|t&t'f�d�_!n�j"j(|||d��s�d�_!�j)d�j#��_)�j#dk�r��*��r�|d�qD|�r
��*��r
|d�qD�fdd�|D�}|�rV|d}|j+�j+k�rV|d�j#�j+|j#|j+f�qD|�r�|d }|�,��j+k�r�|d!�j+|j#|j+f�qD|�r���,�|j+k�r�|d"�j#�j+|j+f�qD|d#t|�d	�j#�j+��,���*�fd�|�-��|j.d$d�d%���*��sd&}�j/�_0|rD|dj+dkrDt1d	t|��D]>}||d	�,�||j+k�r:|d'|t|�fd	��q<�q:d(d�|D�}tj�d�2|���_|d)t�j�t|�fd	��jd
k�r�|d*�t3�j�j�nV�jdk�r�|d+t4�j��n6�jd
k�r2�j�5d,�}�jd|�}|d-t4|��dS�q<qD�j!�sL|d.�dS)/z<Get a response expected to match a given opcode and associd.r9FrNcSs|Srr
�r$r
r
r�<lambda>�rz,ControlSession.getresponse.<locals>.<lambda>cstj��j|�j|�Srr��Ztxt�thr!r
rr�s�zFragment collection beginsr{rbi�z$At %s, select with timeout %d beginsrz"At %s, select with timeout %d endsz$ERR_INCOMPLETE: Received fragments:
z%d: %szlast fragment %sreceived
)znot r9zAt %s, socket read beginsriz'Flaky: I deliberately dropped a packet.zReceived %d octetsrz(AUTH - packet too short for MAC %d < %d
)�
packet_end�	mac_beginz*Received count of 0 in non-final fragment
zReceived second last fragment
csg|]}|j�jkr|�qSr
�r�)rw�frag)�rpktr
rr�*s�z.ControlSession.getresponse.<locals>.<listcomp>z3duplicate %d octets at %d ignored, prior  %d at %d
r|z6received frag at %d overlaps with %d octet frag at %d
z6received %d octet frag at %d overlaps with frag at %d
z@Recording fragment %d, size = %d offset = %d,  end = %d, more=%scSs|jSrr)rr
r
rrJr��keyTz#Hole in fragment sequence, %d of %dcSsg|]}tj�|j��qSr
)rr"ror)rw�fr
r
rr�[s�z3Fragment collection ends. %d bytes  in %d fragmentszResponse packet:
zResponse packet:
%s
�
zFirst line:
%s
z7AUTH: Content untrusted due to authentication failure!
)6r�r�r��MAXFRAGSr��SERR_TOOMUCHr�r�rI�asctime�selectr�r��SERR_SELECT�SERR_TIMEOUTr��	enumerater��SERR_INCOMPLETErr"r#Zrecvr��SERR_SOCKETr��randomrOr�rLrQ�SERR_UNSPEC� _ControlSession__validate_packet�	_authpassr�r��MODE_SIX_HEADER_LENGTH�MODE_SIX_ALIGNMENT�KEYID_LENGTH�MINIMUM_MAC_LENGTH�
verify_macrr�r�r�rT�sortr:r��ranger�r�r�r�)rr�r�ZtimeoZ	fragmentsZseenlastfragZbail�warnr�ZtvoZrd�_�irr�ZvalidZ_pendZnot_earlierr�rZtempfraglistZeol�	firstliner
)rrr�getresponse�s&




��
���� �

�
��������


��
���zControlSession.getresponsecs��jdur�jj}ndd�}�fdd�}|��tjjksH|��tjjkr^|d|��d�dS|��tjjkr�|d|��d�dS|�	�s�|dd�dS|j
�j
kr�|d	|j
�j
fd�dS|��|kr�|d
|��|fd�dS|���r2|�
��r
|d|���d�_�_tttj|��|����|j|k�rP|d|j|f�t|�d
@�rr|dt|��dStj|jd
d@}t|�|k�r�|d|jt|�tjf�tt��dS)NcSs|Srr
rr
r
rrwrz2ControlSession.__validate_packet.<locals>.<lambda>cstj��j|�j|�Srr�rr!r
rrxs�z!Fragment received with version %dr{FzFragment received with mode %dz!Received request, wanted responsez&Received sequence number %d, wanted %dzReceived opcode %d, wanted %dz(Error %d received on non-final fragment
z,Association ID %d doesn't match expected %d
rz(Response fragment not padded, size = %d
���z>Response fragment claims %u octets payload, above %d received
T)r�r�rrrr,r�rr�r�r�r�r�r�r�r�r�r��SERR_SERVERr��
server_errorsr�rOr�rPr�r&)rrr�r�r�r3r�Zshouldbesizer
r!rZ__validate_packetrsz

���

��
��

������z ControlSession.__validate_packetrr9c
Cs�|��stt��d}|�||||�z|�|||�}Wq�ty�}z4|rl|jttfvrld}WYd}~qn|�WYd}~q�d}~00q�q|S)z$send a request and save the responseTFN)r�r��SERR_NOHOSTrr7r1r$r&)rr�r�r�r�Zretryr�r�r
r
r�doquery�szControlSession.doquerycCs�|jtjj|d�t|j�dr(tt��g}|dkr�tt|j�d�D]@}|jd|d|d�}t	�
d|�\}}|�t|||��qF|j
dd�d�|S)z(Read peer status, or throw an exception.)r�r�rrz!HHcSs|jSr)r�)�ar
r
rr�rz)ControlSession.readstat.<locals>.<lambda>r)r<rr�ZCTL_OP_READSTATrOr�r��SERR_BADLENGTHr2rQrRrTr�r1)rr�Zidlistr5rMr:r
r
r�readstat�szControlSession.readstatcCs�g}d}d}tj�|j�|_|jD]h}tj�|�}|dkrJ||7}|}q"|sj|dkrj|�|���d}q"d|kr~dkr"nq"||7}q"|r�|�|���g}|D�]}d|vr�tj�||�	d��\}	}
|
dd	�}
n
|d}	}
|	��|
��}	}
|
�r�zt
|
d�}Wn�t�y�z*t|
�}|	d
k�rB|�sB|�d|
f�Wn@t�y�|
ddk�r||
ddk�r||
dd�}
|
}Yn0Yn0n|
}|�r�|�|	||
ff�q�|�|	|f�q�tj�
|�S)
z&Parse a response as a textual varlist.Fr9�"�,rr��=r{NZdelayzdelay-sr|)rr"ror�r�rT�striprr��indexr[r��float�OrderedDict)r�rawZkvpairsZinstringr�rxZcord�itemsZpairr�valueZcastedvaluer
r
rZ__parse_varlist�sP



zControlSession.__parse_varlistNcCs2|durd}n
d�|�}|j|||d�|�|�S)z@Read system vars from the host as a dict, or throw an exception.Nr9rA)r�r�)r�r<�_ControlSession__parse_varlist)rr�Zvarlistr�rGr�r
r
rr�
s

zControlSession.readvarcCsd|jtjj|dd�|js$tt��n"d|jvrF|jd|j�d��|_|j��|_|jtj	�
d�kS)z?Send configuration text to the daemon. Return True if accepted.T�r�r�r�rNzConfig Succeeded)r<rr�ZCTL_OP_CONFIGUREr�r��SERR_PERMISSIONrD�rstripr"r#)rZ
configtextr
r
r�configs
�

zControlSession.configcCs�td�D]H}|jtjjd�t��|_|j�tj	�
d��rtj	�|j���Sqt
turb|j}n
|j��}|j�d|�tt��dS)zV
Ask for, and get, a nonce that can be replayed.
This combats source address spoofing
r)r�znonce=z## Nonce expected: %sN)r2r<rr�ZCTL_OP_REQ_NONCErIr�r�r�r"r#rorC�str�bytes�decoder�r�r��
SERR_BADNONCE)rr5Zrespr
r
r�fetch_nonce!s

zControlSession.fetch_noncec
Cs�d}d}t|���}g}i}|r,|jtd�|D]�\}	}
|�d|	|
fd�|	dkrbd|	|
f}n|	dkrnq0n
|	dkrxq0|	d	kr�tj�|
�|_q0n
|	d
kr�q0dD]|}|	�	|d�r�|	�
d�\}}
zt|
�}
Wnty�t
t|	��Yn0|
|v�ri|t|
�<|�|
�|
|t|
�|<q�q0|��|D]\}
t�}|jd
7_dD]0}||t|
�v�rHt|||t|
�|��qH|j�|��q,|du�r�||j�|S)z=Extracts data from the key/value list into a more useful formNrztag=%s, val=%sr�nonce�%s=%sz
last.olderz
addr.olderr�zlast.newest)r�r�r�r�r�r�r�r�r�r{)�listrHr1�
mru_kv_keyr�rr�r�r�r��splitr[r�r��SERR_BADTAGrOrTr�r��setattrr�)rr��span�directZmrurTrHZ	fake_listZ	fake_dict�tag�val�prefix�member�idxr
r
rZ
__mru_analyze7sT



zControlSession.__mru_analyzecCs|jdur|�n�|jtjjkrT|�dd�|d7}|dkrBtt��|�d|d�n�|jtjjkr�|rxd}|�dd�n*|jd8_t	||j�}|�d|d�n^|jt
tfvr�|r�td|d�}|�d	|d�ntd|d�}|�d
|d�n|j�r|�||||fS)Nz4no overlap between prior entries and server MRU listr{rz/--->   Restarting from the beginning, retry #%uFz+Reverted to row limit from fragments limit.z0Row limit reduced to %d following CERR_BADVALUE.rbz7Frag limit reduced to %d following incomplete response.z7Row limit reduced to %d following  incomplete response.)
r2rr��CERR_UNKNOWNVARr�r��
SERR_STALL�
CERR_BADVALUEr��minr&r$�max)rr��restarted_count�	cap_frags�limit�fragsr
r
rZ__mru_query_errorjsX
����������z ControlSession.__mru_query_errorc
Csd}d}d}d}t}|dur i}|r2t|�\}}}|��}	t�}
�z�tdt|j�}d|	|f}|r�d|vr|t|d�|d<d|vr�t|d�|d<t|�\}
}||7}z|jt	j
j|d�d	}WnHt�y
}z.d}|�
|||||�}|\}}}}WYd}~n
d}~00|��}|�r"||�|�||
|�}|�r:|}	|
���rH�q�|�s�|�rdtt|d
�}n$tdt|jt|d
|dd��}t��|jt	j
jk�r�|��}	d
|	|�r�dnd|�r�|n||
f}|t|
t|��7}|dur�g|
_q�Wnt�yYn0t|
||�|
S)zRetrieve MRU list datarTNrz%s, frags=%d�resall�resany)r�r�Fr{�!rz%s, %s=%d%srjri)r�parse_mru_variablesrSr�rer��hex�generate_mru_parmsr<rr�ZCTL_OP_READ_MRUr�� _ControlSession__mru_query_errorrJ�_ControlSession__mru_analyzer�rfrIr�Z
NONCE_TIMEOUT�generate_mru_lastseenrOr��KeyboardInterrupt�
stitch_mru)rr�Zrawhookr\rgrh�sorter�sortkeyrjrTr[riZreq_buf�parms�
firstParmsZrecoverable_read_errorsr�r�ZnewNoncer
r
r�mrulist�s�
��"


����zControlSession.mrulistcCs�|jtjj|dd�g}|����D]v\}}|d��r$d|vr$|�d�\}}t|�}|t	|�dkr�t
t	|�|d�D]}|�tj�
��qx||||<q$|S)zRetrieve ordered-list data.TrKr|r�r{)r<rr�ZCTL_OP_READ_ORDLIST_ArJrH�isdigitrXr[rOr2rTrrF)rZlisttypeZstanzasrrI�stemZstanzar5r
r
rZ	__ordlist�s
�zControlSession.__ordlistcCs
|�d�S)zRetrieve reslist data.Zaddr_restrictions��_ControlSession__ordlistr!r
r
r�reslist
szControlSession.reslistcCs
|�d�S)zRetrieve ifstats data.�ifstatsr}r!r
r
rr�szControlSession.ifstats)F)rr9F)r)F)NNN)+r'r(r)r*r�r+rr�ZCERR_UNSPECZCERR_PERMISSIONZCERR_BADFMTZ
CERR_BADOPZ
CERR_BADASSOCrbrdZ
CERR_RESTRICTr:rr�r�r�r�r�r�r�r
r�rr7r*r<r?rJZCTL_OP_READVARr�rNrSrrrqrzr~rr�r
r
r
rr��sL�8)
57@


5�


3'
jr�c
Cs�d}d}t}d|vr�|d}|d=dd�dd�dd�dd�dd�dd�d	d�d
d�dd�dd�d
d�dd�d�}|dkr|d}|dur�|�|�}|dur�tt|��t|���D]t}|dvr�q�q�|�d�s�|�d��r|�d�}t|�dk�s|dt	t
ttd���vr�tt|��q�q�tt|��q�d|v�rBt
|�d��}|d=d|v�rj|�dd�tjjB|d<|d=d|v�r�|�dd�tjjB|d<|d=|||fS)Nr1cSstj�|j�Sr�rr�r�r��r�r
r
rr"rz%parse_mru_variables.<locals>.<lambda>cSstj�|j�Srr�r�r
r
rr$rcSs
|��Sr�r�r�r
r
rr&rcSs|��Srr�r�r
r
rr(rcSs|��Sr�r�r�r
r
rr*rcSs|��Srr�r�r
r
rr,rcSs|jSr�r�r�r
r
rr.rcSs|jSrr�r�r
r
rr0rcSs|jSr�r�r�r
r
rr2rcSs|jSrr�r�r
r
rr4rcSs|jSr�r�r�r
r
rr6rcSs|jSrr�r�r
r
rr8r)�lstintz-lstintr�z-avgintr�z-addrr�z-countZscorez-scoreZdropz-dropr�)ZmincountZmindropZminscorerkrl�kod�limitedZ	maxlstintZ	minlstintZladdr�recentr1rjrizaddr.zlast.r�rbr{rrjr�rlrr�)r�getr��SERR_BADSORTrV�keysr�rXrO�maprOr2�
SERR_BADPARAMr[rrZRES_KODZRES_LIMITED)r�rvrwrjZsortdict�k�knr
r
rrns`	�

(


�

�rncCs�i}g}t|j�D]2\}}|j|vr.g||j<||j�||jf�q|D]$}|t||dd�d�dd�7}qJdd�|D�}|jdd�|D]}|j�|�q�|r�|jj|d�|d	kr�|j��dS)
NcSs|dS)Nr{r
rr
r
rrirzstitch_mru.<locals>.<lambda>rr|cSsg|]}|d�qS)rr
r�r
r
rr�jrzstitch_mru.<locals>.<listcomp>T)�reverser�)	r%r�r�rTr��sortedr1�popr�)r[rvrwZaddrdictZdeletiar5�entryr�r
r
rru[s 

"rucCsV|sdSdd�t|���D�}dd�|�}d|vrJd|d}||7}n|}||fS)N)r9r9cSs g|]}|ddkrd|�qS)rr�rUr
)rw�itr
r
rr�{s�z&generate_mru_parms.<locals>.<listcomp>z, r�z, recent=%s)rVrHr�)r�ZparmStrsrxryr
r
rrpws
�
rpcCsrd}tt|j��D]Z}|jt|j�|d}d||j||jf}|t|�t|�tjjkrdqnq||7}q|S)Nr9r{z, addr.%d=%s, last.%d=%s)r2rOr�r�r�rr�r
)r[ZexistingBufferSize�bufr5r�Zincrr
r
rrs�s�
rscCsF|d�d�}t|�dkrdSzt|d�WSty@YdS0dS)Nrr�r{���r|)rXrOr[r�)�token�bitsr
r
rrW�srWc@sVeZdZdZddd�Zdd�Zdd�Zdd	d
�Zedd��Z	ed
d��Z
ddd�ZdS)r�z+MAC authentication manager for NTP packets.NcCs�i|_|dur�t|�D]|}d|vr4|d|�d��}|��}|sBq|��\}}}|��dvr`d}t|�dkr�tj�	|dd��}||f|jt
|�<qdS)N�#)ZAESZ
AES128CMACzAES-128r	r�)�	passwords�openrDrCrX�upperrOrrr	r[)rZkeyfiler�r�r�r�r
r
rr�szAuthenticator.__init__cCs
t|j�S)z1return the number of keytype/passwd tuples stored)rOr�r!r
r
r�__len__�szAuthenticator.__len__cCs|j�|�S)z#get a keytype/passwd tuple by keyid)r�r�)rr�r
r
r�__getitem__�szAuthenticator.__getitem__cCs�|dur,||jvr"|f|j|S|ddfStd�D]^}|�d�r4t|��d�}|j|\}}|durlt�t|�dkr�tj�	|�}|||fSq4t�dS)z?Get the keytype/passwd tuple that controls localhost and its idNz
/etc/ntp.confr�r{r	)
r�r�r�r[rXr�rOrrr	)rr�r�r�r�r
r
rr��s


zAuthenticator.controlcCsTtj�|�sdStj�tj�|�tj�|�|�}|r@t|�dkrDdSt�d|�|S)z)Create the authentication payload to sendFrr�!I)	rr��	checknamerFr"r#rOrQri)rUr�r�r��mac2r
r
rr�s�zAuthenticator.compute_maccCst|�tjjkS)zDoes this packet have a MAC?)rOrrZ
LEN_PKT_NOMAC)�packetr
r
r�have_mac�szAuthenticator.have_macr8c
Cs�|d|�}|||t�}||td�}t�d|�\}||jvrHdS|j|\}}tj�|�sfdStj�tj�	|�tj�	|�|�}	|	s�dSzt
�||	�WSty�||	kYS0dS)zDDoes the MAC on this packet verify according to credentials we have?Nr�F)
r.rQrRr�rr�r�rFr"r#�hmac�compare_digestr�)
rr�rrrUr�rFr�r�r�r
r
rr0�s$
�zAuthenticator.verify_mac)N)N)r8r8)r'r(r)r*rr�r�r�r+rr�r0r
r
r
rr��s




r�)Hr*Z
__future__rrrr�rr(r"r�rvrQr�rIZntp.controlrZ	ntp.magicZntp.ntpcZntp.utilZntp.polyrr�r�rr,r/r.r-ZMAX_BARE_MAC_LENGTHr
�
BaseExceptionr/r7r�r�ZSERR_BADFMTrLZ
SERR_BADOPZ
SERR_BADASSOCZSERR_UNKNOWNVARZ
SERR_BADVALUEr)r'r$r&r r#r;r>rrrrRr�rr9rcrYr�r�r�r�r�r�r�r�rnrurprsrWr�r
r
r
r�<module>s�L
(	DD(
WH