File: //usr/lib64/python3.9/site-packages/ntp/__pycache__/packet.cpython-39.pyc
a
\��dk � @ s� d Z ddlmZmZ ddlZddlZddlZddlZddlZddl Z ddl
Z
ddlZddlZddl
Z
ddlZddlZddlZddlZddlZdZdZdZdZdZd Zd
ZdZdZG d
d� d�ZG dd� de�ZG dd� de�Z G dd� de�Z!G dd� 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;ej<fd0d1�Z=G d2d3� d3�Z>G d4d5� d5�Z?G d6d7� d7e�Z@G d8d9� d9�ZAd:d;� ZBd<d=� ZCd>d?� ZDd@dA� ZEdBdC� ZFG dDdE� 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 @ sr e Zd ZdZedd� �Zedd� �Zejj ejj
dfdd�Zed d
� �Z
e
jdd
� �Z
dd
� Zdd� Zdd� ZdS )�PacketzEncapsulate an NTP fragmentc C s | d@ d>