1 // Copyright 2016 Google, Inc. All rights reserved.
3 // Use of this source code is governed by a BSD-style license
4 // that can be found in the LICENSE file in the root of the source
7 //******************************************************************************
13 "github.com/google/gopacket"
19 //******************************************************************************
21 // checkNTP() uses the ntp.go code to analyse the packet bytes as an NTP UDP
22 // packet and generate an NTP object. It then compares the generated NTP object
23 // with the one provided and throws an error if there is any difference.
24 // The desc argument is output with any failure message to identify the test.
25 func checkNTP(desc string, t *testing.T, packetBytes []byte, pExpectedNTP *NTP) {
27 // Analyse the packet bytes, yielding a new packet object p.
28 p := gopacket.NewPacket(packetBytes, LinkTypeEthernet, gopacket.Default)
29 if p.ErrorLayer() != nil {
30 t.Errorf("Failed to decode packet %s: %v", desc, p.ErrorLayer().Error())
33 // Ensure that the packet analysis yielded the correct set of layers:
34 // Link Layer = Ethernet.
35 // Network Layer = IPv4.
36 // Transport Layer = UDP.
37 // Application Layer = NTP.
38 checkLayers(p, []gopacket.LayerType{
44 // Select the Application (NTP) layer.
45 pResultNTP, ok := p.ApplicationLayer().(*NTP)
47 t.Error("No NTP layer type found in packet in " + desc + ".")
50 // Compare the generated NTP object with the expected NTP object.
51 if !reflect.DeepEqual(pResultNTP, pExpectedNTP) {
52 t.Errorf("NTP packet processing failed for packet "+desc+
53 ":\ngot :\n%#v\n\nwant :\n%#v\n\n", pResultNTP, pExpectedNTP)
55 buf := gopacket.NewSerializeBuffer()
56 opts := gopacket.SerializeOptions{}
57 err := pResultNTP.SerializeTo(buf, opts)
61 if !reflect.DeepEqual(pResultNTP.BaseLayer.Contents, buf.Bytes()) {
62 t.Errorf("NTP packet serialization failed for packet "+desc+
63 ":\ngot :\n%x\n\nwant :\n%x\n\n", buf.Bytes(), packetBytes)
67 //******************************************************************************
69 func TestNTPOne(t *testing.T) {
71 // This test packet is the first NTP packet in the NTP sample capture
72 // pcap file NTP_sync.pcap on the Wireshark sample captures page:
74 // https://wiki.wireshark.org/SampleCaptures
75 // https://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=get&target=NTP_sync.pcap
76 var testPacketNTP = []byte{
77 0x00, 0x0c, 0x41, 0x82, 0xb2, 0x53, 0x00, 0xd0,
78 0x59, 0x6c, 0x40, 0x4e, 0x08, 0x00, 0x45, 0x00,
79 0x00, 0x4c, 0x0a, 0x42, 0x00, 0x00, 0x80, 0x11,
80 0xb5, 0xfa, 0xc0, 0xa8, 0x32, 0x32, 0x43, 0x81,
81 0x44, 0x09, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x38,
82 0xf8, 0xd2, 0xd9, 0x00, 0x0a, 0xfa, 0x00, 0x00,
83 0x00, 0x00, 0x00, 0x01, 0x02, 0x90, 0x00, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87 0x00, 0x00, 0xc5, 0x02, 0x04, 0xec, 0xec, 0x42,
91 // Assemble the NTP object that we expect to emerge from this test.
94 Contents: []byte{0xd9, 0x0, 0xa, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x0,
95 0x1, 0x2, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
96 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
97 0x0, 0x0, 0x0, 0x0, 0x0, 0xc5, 0x2, 0x4, 0xec, 0xec, 0x42, 0xee, 0x92},
107 RootDispersion: 0x10290,
109 ReferenceTimestamp: 0,
112 TransmitTimestamp: 0xc50204ecec42ee92,
113 ExtensionBytes: []byte{},
116 checkNTP("test01", t, testPacketNTP, pExpectedNTP)
119 //******************************************************************************
121 func TestNTPTwo(t *testing.T) {
123 // This test packet is packet #18 in the NTP sample capture
124 // pcap file NTP_sync.pcap on the Wireshark sample captures page:
126 // https://wiki.wireshark.org/SampleCaptures
127 // https://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=get&target=NTP_sync.pcap
129 // This packet was chosen because it is the first NTP packet after the first
130 // NTP packet that has non-zero timestamps.
132 var testPacketNTP = []byte{
133 0x00, 0xd0, 0x59, 0x6c, 0x40, 0x4e, 0x00, 0x0c,
134 0x41, 0x82, 0xb2, 0x53, 0x08, 0x00, 0x45, 0x00,
135 0x00, 0x4c, 0x32, 0x46, 0x40, 0x00, 0x2f, 0x11,
136 0xa8, 0x18, 0x45, 0x2c, 0x39, 0x3c, 0xc0, 0xa8,
137 0x32, 0x32, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x38,
138 0x09, 0x58, 0x1a, 0x03, 0x0a, 0xee, 0x00, 0x00,
139 0x1b, 0xf7, 0x00, 0x00, 0x14, 0xec, 0x51, 0xae,
140 0x80, 0xb7, 0xc5, 0x02, 0x03, 0x4c, 0x8d, 0x0e,
141 0x66, 0xcb, 0xc5, 0x02, 0x04, 0xec, 0xec, 0x42,
142 0xee, 0x92, 0xc5, 0x02, 0x04, 0xeb, 0xcf, 0x49,
143 0x59, 0xe6, 0xc5, 0x02, 0x04, 0xeb, 0xcf, 0x4c,
147 // Assemble the NTP object that we expect to emerge from this test.
148 pExpectedNTP := &NTP{
149 BaseLayer: BaseLayer{
150 Contents: []byte{0x1a, 0x03, 0x0a, 0xee, 0x00, 0x00,
151 0x1b, 0xf7, 0x00, 0x00, 0x14, 0xec, 0x51, 0xae,
152 0x80, 0xb7, 0xc5, 0x02, 0x03, 0x4c, 0x8d, 0x0e,
153 0x66, 0xcb, 0xc5, 0x02, 0x04, 0xec, 0xec, 0x42,
154 0xee, 0x92, 0xc5, 0x02, 0x04, 0xeb, 0xcf, 0x49,
155 0x59, 0xe6, 0xc5, 0x02, 0x04, 0xeb, 0xcf, 0x4c,
166 RootDispersion: 0x14ec,
167 ReferenceID: 0x51ae80b7,
168 ReferenceTimestamp: 0xc502034c8d0e66cb,
169 OriginTimestamp: 0xc50204ecec42ee92,
170 ReceiveTimestamp: 0xc50204ebcf4959e6,
171 TransmitTimestamp: 0xc50204ebcf4c6e6e,
172 ExtensionBytes: []byte{},
175 checkNTP("test02", t, testPacketNTP, pExpectedNTP)
178 //******************************************************************************
180 func TestNTPThree(t *testing.T) {
182 // This test packet is packet #19 in the NTP sample capture
183 // pcap file NTP_sync.pcap on the Wireshark sample captures page:
185 // https://wiki.wireshark.org/SampleCaptures
186 // https://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=get&target=NTP_sync.pcap
188 var testPacketNTP = []byte{
189 0x00, 0xd0, 0x59, 0x6c, 0x40, 0x4e, 0x00, 0x0c,
190 0x41, 0x82, 0xb2, 0x53, 0x08, 0x00, 0x45, 0x00,
191 0x00, 0x4c, 0x00, 0x00, 0x40, 0x00, 0x30, 0x11,
192 0x74, 0x65, 0x18, 0x7b, 0xca, 0xe6, 0xc0, 0xa8,
193 0x32, 0x32, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x38,
194 0x44, 0x05, 0x1a, 0x02, 0x0a, 0xec, 0x00, 0x00,
195 0x07, 0xc3, 0x00, 0x00, 0x2f, 0x80, 0xc6, 0x1e,
196 0x5c, 0x02, 0xc5, 0x01, 0xf9, 0x95, 0x42, 0x50,
197 0x82, 0xcf, 0xc5, 0x02, 0x04, 0xec, 0xec, 0x42,
198 0xee, 0x92, 0xc5, 0x02, 0x04, 0xeb, 0xd2, 0x35,
199 0x2e, 0xb5, 0xc5, 0x02, 0x04, 0xeb, 0xd2, 0x35,
203 // Assemble the NTP object that we expect to emerge from this test.
204 pExpectedNTP := &NTP{
205 BaseLayer: BaseLayer{
206 Contents: []byte{0x1a, 0x02, 0x0a, 0xec, 0x00, 0x00,
207 0x07, 0xc3, 0x00, 0x00, 0x2f, 0x80, 0xc6, 0x1e,
208 0x5c, 0x02, 0xc5, 0x01, 0xf9, 0x95, 0x42, 0x50,
209 0x82, 0xcf, 0xc5, 0x02, 0x04, 0xec, 0xec, 0x42,
210 0xee, 0x92, 0xc5, 0x02, 0x04, 0xeb, 0xd2, 0x35,
211 0x2e, 0xb5, 0xc5, 0x02, 0x04, 0xeb, 0xd2, 0x35,
222 RootDispersion: 0x2f80,
223 ReferenceID: 0xc61e5c02,
224 ReferenceTimestamp: 0xc501f995425082cf,
225 OriginTimestamp: 0xc50204ecec42ee92,
226 ReceiveTimestamp: 0xc50204ebd2352eb5,
227 TransmitTimestamp: 0xc50204ebd235d67b,
228 ExtensionBytes: []byte{},
231 checkNTP("test03", t, testPacketNTP, pExpectedNTP)
234 //******************************************************************************
236 // TestNTPIsomorphism tests whether random data gets parsed into NTP layer and
237 // gets serialized back from it to the same value.
238 func TestNTPIsomorphism(t *testing.T) {
239 NTPData := make([]byte, ntpMinimumRecordSizeInBytes+7)
240 _, err := io.ReadFull(rand.Reader, NTPData)
245 err = ntpLayer.DecodeFromBytes(NTPData, gopacket.NilDecodeFeedback)
249 buf := gopacket.NewSerializeBuffer()
250 opts := gopacket.SerializeOptions{}
251 err = ntpLayer.SerializeTo(buf, opts)
255 if !reflect.DeepEqual(NTPData, buf.Bytes()) {
256 t.Errorf("NTP packet is not isomorphic:\ngot :\n%x\n\nwant :\n%x\n\n", buf.Bytes(), NTPData)