Ho ngola moreki ea bonolo oa NTP

Lumelang habrausers. Kajeno ke batla ho bua ka mokhoa oa ho ngola moreki oa hau o bonolo oa NTP. Ha e le hantle, moqoqo o tla fetohela ho sebopeho sa pakete le hore na karabo e tsoang ho seva sa NTP e sebetsoa joang. Khoutu e tla ngoloa ka python, hobane, ka maikutlo a ka, ha ho na puo e molemo feela bakeng sa lintho tse joalo. Li-Connoisseurs li tla ela hloko ho tšoana ha khoutu le khoutu ea ntplib - ke "bululetsoe" ke eona.

Joale NTP ke eng? NTP ke protocol ea ho buisana le li-server tsa nako. Protocol ena e sebelisoa mecheng e mengata ea sejoale-joale. Mohlala, ts'ebeletso ea w32tm lifensetereng.

Ho na le liphetolelo tse 5 tsa protocol ea NTP ka kakaretso. Ea pele, mofuta oa 0 (1985, RFC958) hajoale o nkuoa e le oa khale. Tse ncha li sebelisoa hajoale, 1st (1988, RFC1059), 2nd (1989, RFC1119), 3rd (1992, RFC1305) le 4th (1996, RFC2030). Liphetolelo tsa 1-4 lia lumellana, li fapana feela ka li-algorithms tsa li-server.

Sebopeho sa Pakete

Ho ngola moreki ea bonolo oa NTP

Leap indicator (correction indicator) ke nomoro e bontšang tlhokomeliso ea bobeli ea leap. Tlhaloso:

  • 0 - ha ho khalemelo
  • 1 - motsotso oa ho qetela oa letsatsi o na le metsotsoana e 61
  • 2 - motsotso oa ho qetela oa letsatsi o na le metsotsoana e 59
  • 3 - ho hloleha ha seva (nako e felile ho sync)

Nomoro ea phetolelo (nomoro ea phetolelo) - Nomoro ea phetolelo ea protocol ea NTP (1-4).

feshene (mokhoa) - mokhoa oa ts'ebetso oa moromeli oa pakete. Boleng ho tloha ho 0 ho isa ho 7, e tloaelehileng haholo:

  • 3 - moreki
  • 4 - seva
  • 5 - mokhoa oa ho phatlalatsa

Letlalo (boemo ba mekhahlelo) - palo ea lihlopha tse bohareng pakeng tsa seva le oache ea litšupiso (1 - seva se nka data ka ho toba ho tloha ho nako ea boitsebiso, 2 - seva se nka data ho tswa ho seva ka boemo ba 1, joalo-joalo).
Pool ke nomoro e saennoeng e emelang boholo ba nako pakeng tsa melaetsa e latellanang. Moreki oa NTP o bolela mona nako eo e lebeletseng ho khetha seva ka eona, 'me seva sa NTP se bolela nako eo e lebeletseng ho etsoa ka eona. Boleng bo lekana le binary logarithm ea metsotsoana.
sebetsa ka ho nepahetseng (precision) ke nomoro e saennoeng e emelang ho nepahala ha oache ea sistimi. Boleng bo lekana le binary logarithm ea metsotsoana.
tieho ea metso (latency ea seva) ke nako eo e e nkang hore oache e fihle ho seva sa NTP, e le palo e tsitsitseng ea metsotsoana.
ho hasana ha metso (Server scatter) - Ho hasana ha oache ea seva sa NTP e le palo e tsitsitseng ea metsotsoana.
Ref id (ID ea mohloli) - id ea ho shebella. Haeba seva se na le stratum 1, joale ref id ke lebitso la oache ea athomo (litlhaku tse 4 tsa ASCII). Haeba seva se sebelisa seva se seng, joale ref id e na le aterese ea seva sena.
Mabala a 4 a ho qetela ke nako - likotoana tse 32 - karolo e felletseng, likotoana tse 32 - karolo ea karoloana.
Reference - oache ea morao-rao ho seva.
Qaleho - nako eo pakete e rometsoeng (e tlatsitsoeng ke seva - ho feta moo ka tlase).
Amohela – nako eo sephutheloana se ileng sa amoheloa ka eona ke seva.
fetisetsa - nako eo pakete e rometsoeng ho tloha ho seva ho ea ho mofani (e tlatsitsoeng ke mofani, ho feta ka tlase).

Ho ke ke ha shejoa masimo a mabeli a ho qetela.

Ha re ngoleng sephutheloana sa rona:

Khoutu ea sephutheloana

class NTPPacket:
    _FORMAT = "!B B b b 11I"

    def __init__(self, version_number=2, mode=3, transmit=0):
        # Necessary of enter leap second (2 bits)
        self.leap_indicator = 0
        # Version of protocol (3 bits)
        self.version_number = version_number
        # Mode of sender (3 bits)
        self.mode = mode
        # The level of "layering" reading time (1 byte)
        self.stratum = 0
        # Interval between requests (1 byte)
        self.pool = 0
        # Precision (log2) (1 byte)
        self.precision = 0
        # Interval for the clock reach NTP server (4 bytes)
        self.root_delay = 0
        # Scatter the clock NTP-server (4 bytes)
        self.root_dispersion = 0
        # Indicator of clocks (4 bytes)
        self.ref_id = 0
        # Last update time on server (8 bytes)
        self.reference = 0
        # Time of sending packet from local machine (8 bytes)
        self.originate = 0
        # Time of receipt on server (8 bytes)
        self.receive = 0
        # Time of sending answer from server (8 bytes)
        self.transmit = transmit

Ho romela (le ho amohela) pakete ho seva, re tlameha ho khona ho e fetola hore e be li-byte tse ngata.
Bakeng sa ts'ebetso ena (le ho khutlisetsa morao), re tla ngola mesebetsi e 'meli - pack() le unpack():

mosebetsi oa pakete

def pack(self):
        return struct.pack(NTPPacket._FORMAT,
                (self.leap_indicator << 6) + 
                    (self.version_number << 3) + self.mode,
                self.stratum,
                self.pool,
                self.precision,
                int(self.root_delay) + get_fraction(self.root_delay, 16),
                int(self.root_dispersion) + 
                    get_fraction(self.root_dispersion, 16),
                self.ref_id,
                int(self.reference),
                get_fraction(self.reference, 32),
                int(self.originate),
                get_fraction(self.originate, 32),
                int(self.receive),
                get_fraction(self.receive, 32),
                int(self.transmit),
                get_fraction(self.transmit, 32))

mosebetsi oa ho manolla

def unpack(self, data: bytes):
        unpacked_data = struct.unpack(NTPPacket._FORMAT, data)

        self.leap_indicator = unpacked_data[0] >> 6  # 2 bits
        self.version_number = unpacked_data[0] >> 3 & 0b111  # 3 bits
        self.mode = unpacked_data[0] & 0b111  # 3 bits

        self.stratum = unpacked_data[1]  # 1 byte
        self.pool = unpacked_data[2]  # 1 byte
        self.precision = unpacked_data[3]  # 1 byte

        # 2 bytes | 2 bytes
        self.root_delay = (unpacked_data[4] >> 16) +
            (unpacked_data[4] & 0xFFFF) / 2 ** 16
         # 2 bytes | 2 bytes
        self.root_dispersion = (unpacked_data[5] >> 16) +
            (unpacked_data[5] & 0xFFFF) / 2 ** 16 

        # 4 bytes
        self.ref_id = str((unpacked_data[6] >> 24) & 0xFF) + " " + 
                      str((unpacked_data[6] >> 16) & 0xFF) + " " +  
                      str((unpacked_data[6] >> 8) & 0xFF) + " " +  
                      str(unpacked_data[6] & 0xFF)

        self.reference = unpacked_data[7] + unpacked_data[8] / 2 ** 32  # 8 bytes
        self.originate = unpacked_data[9] + unpacked_data[10] / 2 ** 32  # 8 bytes
        self.receive = unpacked_data[11] + unpacked_data[12] / 2 ** 32  # 8 bytes
        self.transmit = unpacked_data[13] + unpacked_data[14] / 2 ** 32  # 8 bytes

        return self

Bakeng sa batho ba botsoa, ​​e le kopo - khoutu e fetolang sephutheloana hore e be khoele e ntle

def to_display(self):
        return "Leap indicator: {0.leap_indicator}n" 
                "Version number: {0.version_number}n" 
                "Mode: {0.mode}n" 
                "Stratum: {0.stratum}n" 
                "Pool: {0.pool}n" 
                "Precision: {0.precision}n" 
                "Root delay: {0.root_delay}n" 
                "Root dispersion: {0.root_dispersion}n" 
                "Ref id: {0.ref_id}n" 
                "Reference: {0.reference}n" 
                "Originate: {0.originate}n" 
                "Receive: {0.receive}n" 
                "Transmit: {0.transmit}"
                .format(self)

Ho romella sephutheloana ho seva

Romela pakete e nang le libaka tse tlatsitsoeng ho seva Version, feshene и fetisetsa. The fetisetsa o tlameha ho hlakisa nako ea hajoale mochining oa lehae (palo ea metsotsoana ho tloha ka la 1 Pherekhong 1900), mofuta - efe kapa efe ea 1-4, mokhoa - 3 (mokhoa oa bareki).

Seva, ha e se e fumane kopo, e tlatsa masimo ohle a pakete ea NTP, e kopitse tšimong Qaleho boleng ho tloha fetisetsa, e tlileng ka kopo. Ke sephiri ho 'na hore na ke hobane'ng ha moreki a ke ke a tlatsa hang-hang boleng ba nako ea hae tšimong Qaleho. Ka lebaka leo, ha pakete e khutla, moreki o na le litekanyetso tsa nako tse 4 - nako eo kopo e rometsoeng ka eona (Qaleho), nako eo seva e amohetseng kopo (Amohela), nako eo seva e rometseng karabo (fetisetsa) le nako ea ho fumana karabo ke moreki - Fihla (eseng ka har'a sephutheloana). Ka litekanyetso tsena re ka beha nako e nepahetseng.

Khoutu ea ho romela le ho amohela sephutheloana

# Time difference between 1970 and 1900, seconds
FORMAT_DIFF = (datetime.date(1970, 1, 1) - datetime.date(1900, 1, 1)).days * 24 * 3600
# Waiting time for recv (seconds)
WAITING_TIME = 5
server = "pool.ntp.org"
port = 123
    
packet = NTPPacket(version_number=2, mode=3, transmit=time.time() + FORMAT_DIFF)
answer = NTPPacket()
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
    s.settimeout(WAITING_TIME)
    s.sendto(packet.pack(), (server, port))
    data = s.recv(48)
    arrive_time = time.time() + FORMAT_DIFF
    answer.unpack(data)

Ts'ebetso ea data ho tsoa ho seva

Ts'ebetso ea data ho tsoa ho seva e tšoana le liketso tsa mohlomphehi oa Lenyesemane ho tsoa bothateng ba khale ba Raymond M. Smallian (1978): "Motho a le mong o ne a se na oache ea letsoho, empa ho ne ho e-na le oache e nepahetseng ea lebota lapeng, eo a neng a e-na le eona. ka nako tse ding ke lebetse moya. Ka letsatsi le leng, a lebala ho qala oache hape, o ile a etela motsoalle oa hae, a qeta mantsiboea le eena, 'me ha a khutlela hae, a khona ho beha oache hantle. O ile a khona ho etsa see joang haeba nako ea leeto e ne e sa tsejoe esale pele? Karabo ke hore: “Ha motho a tloha ka tlung, o phahamisa oache ’me o hopola boemo ba matsoho. Ho tla ho motsoalle le ho siea baeti, o hlokomela nako ea ho fihla le ho tloha ha hae. Sena se mo nolofalletsa ho fumana hore na o tsamaile nako e kae. Ha motho a khutlela hae ’me a sheba oache, ke eena ea tsebang hore na o tla be a le sieo neng. Ho tlosa nakong ena nako eo a e qetileng a etela, motho o fumana nako eo a e qetileng a le tseleng e eang moo le ho khutla. Ka ho eketsa halofo ea nako e sebelisoang tseleng ho ea ho nako ea ho siea baeti, o fumana monyetla oa ho fumana nako ea ho fihla hae le ho lokisa matsoho a oache ea hae ka tsela e nepahetseng.

Fumana nako eo sebatli e neng e sebetsa ka eona kopong:

  1. Ho fumana nako ea leeto la pakete ho tloha ho moreki ho ea ho seva: ((Fihla - Origine) - (Fetisetsa - Amohela)) / 2
  2. Fumana phapang lipakeng tsa nako ea moreki le seva:
    Amohela - E simolohile - ((Fihla - Origine) - (Fetisetsa - Amohela)) / 2 =
    2 * Amohela - 2 * Qala - Fihla + Origine + Fetisa - Amohela =
    Amohela - Qala - Fihla + Fetisa

Re eketsa boleng boo re bo fumaneng nakong ea sebaka seo 'me re thabela bophelo.

Sephetho sa Sephetho

time_different = answer.get_time_different(arrive_time)
result = "Time difference: {}nServer time: {}n{}".format(
    time_different,
    datetime.datetime.fromtimestamp(time.time() + time_different).strftime("%c"),
    answer.to_display())
print(result)

E molemo link.

Source: www.habr.com

Eketsa ka tlhaloso