1f7d24e3fSHanoh Haim## This file is part of Scapy
2f7d24e3fSHanoh Haim## See http://www.secdev.org/projects/scapy for more informations
3f7d24e3fSHanoh Haim## Copyright (C) Philippe Biondi <phil@secdev.org>
4f7d24e3fSHanoh Haim## This program is published under a GPLv2 license
5f7d24e3fSHanoh Haim
6f7d24e3fSHanoh Haim"""
7f7d24e3fSHanoh HaimNTP (Network Time Protocol).
8f7d24e3fSHanoh Haim"""
9f7d24e3fSHanoh Haim
10f7d24e3fSHanoh Haimimport time
11f7d24e3fSHanoh Haimfrom scapy.packet import *
12f7d24e3fSHanoh Haimfrom scapy.fields import *
13f7d24e3fSHanoh Haimfrom scapy.layers.inet import UDP
14f7d24e3fSHanoh Haim
15f7d24e3fSHanoh Haim
16f7d24e3fSHanoh Haim# seconds between 01-01-1900 and 01-01-1970
17f7d24e3fSHanoh Haim_NTP_BASETIME = 2208988800
18f7d24e3fSHanoh Haim
19f7d24e3fSHanoh Haimclass TimeStampField(FixedPointField):
20f7d24e3fSHanoh Haim    def __init__(self, name, default):
21f7d24e3fSHanoh Haim        FixedPointField.__init__(self, name, default, 64, 32)
22f7d24e3fSHanoh Haim
23f7d24e3fSHanoh Haim    def i2repr(self, pkt, val):
24f7d24e3fSHanoh Haim        if val is None:
25f7d24e3fSHanoh Haim            return "--"
26f7d24e3fSHanoh Haim        val = self.i2h(pkt,val)
27f7d24e3fSHanoh Haim        if val < _NTP_BASETIME:
28f7d24e3fSHanoh Haim            return val
29f7d24e3fSHanoh Haim        return time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime(val-_NTP_BASETIME))
30f7d24e3fSHanoh Haim
31f7d24e3fSHanoh Haim    def any2i(self, pkt, val):
32f7d24e3fSHanoh Haim        if type(val) is str:
33f7d24e3fSHanoh Haim            return int(time.mktime(time.strptime(val))) + _NTP_BASETIME + 3600 # XXX
34f7d24e3fSHanoh Haim        return FixedPointField.any2i(self,pkt,val)
35f7d24e3fSHanoh Haim
36f7d24e3fSHanoh Haim    def i2m(self, pkt, val):
37f7d24e3fSHanoh Haim        if val is None:
38f7d24e3fSHanoh Haim            val = FixedPointField.any2i(self, pkt, time.time()+_NTP_BASETIME)
39f7d24e3fSHanoh Haim        return FixedPointField.i2m(self, pkt, val)
40f7d24e3fSHanoh Haim
41f7d24e3fSHanoh Haim
42f7d24e3fSHanoh Haim
43f7d24e3fSHanoh Haimclass NTP(Packet):
44f7d24e3fSHanoh Haim    # RFC 1769
45f7d24e3fSHanoh Haim    name = "NTP"
46f7d24e3fSHanoh Haim    fields_desc = [
47f7d24e3fSHanoh Haim         BitEnumField('leap', 0, 2,
48f7d24e3fSHanoh Haim                      { 0: 'nowarning',
49f7d24e3fSHanoh Haim                        1: 'longminute',
50f7d24e3fSHanoh Haim                        2: 'shortminute',
51f7d24e3fSHanoh Haim                        3: 'notsync'}),
52f7d24e3fSHanoh Haim         BitField('version', 3, 3),
53f7d24e3fSHanoh Haim         BitEnumField('mode', 3, 3,
54f7d24e3fSHanoh Haim                      { 0: 'reserved',
55f7d24e3fSHanoh Haim                        1: 'sym_active',
56f7d24e3fSHanoh Haim                        2: 'sym_passive',
57f7d24e3fSHanoh Haim                        3: 'client',
58f7d24e3fSHanoh Haim                        4: 'server',
59f7d24e3fSHanoh Haim                        5: 'broadcast',
60f7d24e3fSHanoh Haim                        6: 'control',
61f7d24e3fSHanoh Haim                        7: 'private'}),
62f7d24e3fSHanoh Haim         BitField('stratum', 2, 8),
63f7d24e3fSHanoh Haim         BitField('poll', 0xa, 8),          ### XXX : it's a signed int
64f7d24e3fSHanoh Haim         BitField('precision', 0, 8),       ### XXX : it's a signed int
65f7d24e3fSHanoh Haim         FixedPointField('delay', 0, size=32, frac_bits=16),
66f7d24e3fSHanoh Haim         FixedPointField('dispersion', 0, size=32, frac_bits=16),
67f7d24e3fSHanoh Haim         IPField('id', "127.0.0.1"),
68f7d24e3fSHanoh Haim         TimeStampField('ref', 0),
69f7d24e3fSHanoh Haim         TimeStampField('orig', None),  # None means current time
70f7d24e3fSHanoh Haim         TimeStampField('recv', 0),
71f7d24e3fSHanoh Haim         TimeStampField('sent', None)
72f7d24e3fSHanoh Haim         ]
73f7d24e3fSHanoh Haim    def mysummary(self):
74f7d24e3fSHanoh Haim        return self.sprintf("NTP v%ir,NTP.version%, %NTP.mode%")
75f7d24e3fSHanoh Haim
76f7d24e3fSHanoh Haim
77f7d24e3fSHanoh Haimbind_layers( UDP,           NTP,           dport=123, sport=123)
78