github.com/gopacket/gopacket@v1.1.0/layers/ntp_test.go (about)

     1  // Copyright 2016 Google, Inc. All rights reserved.
     2  //
     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
     5  // tree.
     6  //
     7  //******************************************************************************
     8  
     9  package layers
    10  
    11  import (
    12  	"crypto/rand"
    13  	"io"
    14  	"reflect"
    15  	"testing"
    16  
    17  	"github.com/gopacket/gopacket"
    18  )
    19  
    20  //******************************************************************************
    21  
    22  // checkNTP() uses the ntp.go code to analyse the packet bytes as an NTP UDP
    23  // packet and generate an NTP object. It then compares the generated NTP object
    24  // with the one provided and throws an error if there is any difference.
    25  // The desc argument is output with any failure message to identify the test.
    26  func checkNTP(desc string, t *testing.T, packetBytes []byte, pExpectedNTP *NTP) {
    27  
    28  	// Analyse the packet bytes, yielding a new packet object p.
    29  	p := gopacket.NewPacket(packetBytes, LinkTypeEthernet, gopacket.Default)
    30  	if p.ErrorLayer() != nil {
    31  		t.Errorf("Failed to decode packet %s: %v", desc, p.ErrorLayer().Error())
    32  	}
    33  
    34  	// Ensure that the packet analysis yielded the correct set of layers:
    35  	//    Link Layer        = Ethernet.
    36  	//    Network Layer     = IPv4.
    37  	//    Transport Layer   = UDP.
    38  	//    Application Layer = NTP.
    39  	checkLayers(p, []gopacket.LayerType{
    40  		LayerTypeEthernet,
    41  		LayerTypeIPv4,
    42  		LayerTypeUDP,
    43  		LayerTypeNTP}, t)
    44  
    45  	// Select the Application (NTP) layer.
    46  	pResultNTP, ok := p.ApplicationLayer().(*NTP)
    47  	if !ok {
    48  		t.Error("No NTP layer type found in packet in " + desc + ".")
    49  	}
    50  
    51  	// Compare the generated NTP object with the expected NTP object.
    52  	if !reflect.DeepEqual(pResultNTP, pExpectedNTP) {
    53  		t.Errorf("NTP packet processing failed for packet "+desc+
    54  			":\ngot  :\n%#v\n\nwant :\n%#v\n\n", pResultNTP, pExpectedNTP)
    55  	}
    56  	buf := gopacket.NewSerializeBuffer()
    57  	opts := gopacket.SerializeOptions{}
    58  	err := pResultNTP.SerializeTo(buf, opts)
    59  	if err != nil {
    60  		t.Error(err)
    61  	}
    62  	if !reflect.DeepEqual(pResultNTP.BaseLayer.Contents, buf.Bytes()) {
    63  		t.Errorf("NTP packet serialization failed for packet "+desc+
    64  			":\ngot  :\n%x\n\nwant :\n%x\n\n", buf.Bytes(), packetBytes)
    65  	}
    66  }
    67  
    68  //******************************************************************************
    69  
    70  func TestNTPOne(t *testing.T) {
    71  
    72  	// This test packet is the first NTP packet in the NTP sample capture
    73  	// pcap file NTP_sync.pcap on the Wireshark sample captures page:
    74  	//
    75  	//    https://wiki.wireshark.org/SampleCaptures
    76  	//    https://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=get&target=NTP_sync.pcap
    77  	var testPacketNTP = []byte{
    78  		0x00, 0x0c, 0x41, 0x82, 0xb2, 0x53, 0x00, 0xd0,
    79  		0x59, 0x6c, 0x40, 0x4e, 0x08, 0x00, 0x45, 0x00,
    80  		0x00, 0x4c, 0x0a, 0x42, 0x00, 0x00, 0x80, 0x11,
    81  		0xb5, 0xfa, 0xc0, 0xa8, 0x32, 0x32, 0x43, 0x81,
    82  		0x44, 0x09, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x38,
    83  		0xf8, 0xd2, 0xd9, 0x00, 0x0a, 0xfa, 0x00, 0x00,
    84  		0x00, 0x00, 0x00, 0x01, 0x02, 0x90, 0x00, 0x00,
    85  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    86  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    87  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    88  		0x00, 0x00, 0xc5, 0x02, 0x04, 0xec, 0xec, 0x42,
    89  		0xee, 0x92,
    90  	}
    91  
    92  	// Assemble the NTP object that we expect to emerge from this test.
    93  	pExpectedNTP := &NTP{
    94  		BaseLayer: BaseLayer{
    95  			Contents: []byte{0xd9, 0x0, 0xa, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x0,
    96  				0x1, 0x2, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    97  				0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    98  				0x0, 0x0, 0x0, 0x0, 0x0, 0xc5, 0x2, 0x4, 0xec, 0xec, 0x42, 0xee, 0x92},
    99  			Payload: nil,
   100  		},
   101  		LeapIndicator:      3,
   102  		Version:            3,
   103  		Mode:               1,
   104  		Stratum:            0,
   105  		Poll:               10,
   106  		Precision:          -6,
   107  		RootDelay:          0,
   108  		RootDispersion:     0x10290,
   109  		ReferenceID:        0,
   110  		ReferenceTimestamp: 0,
   111  		OriginTimestamp:    0,
   112  		ReceiveTimestamp:   0,
   113  		TransmitTimestamp:  0xc50204ecec42ee92,
   114  		ExtensionBytes:     []byte{},
   115  	}
   116  
   117  	checkNTP("test01", t, testPacketNTP, pExpectedNTP)
   118  }
   119  
   120  //******************************************************************************
   121  
   122  func TestNTPTwo(t *testing.T) {
   123  
   124  	// This test packet is packet #18 in the NTP sample capture
   125  	// pcap file NTP_sync.pcap on the Wireshark sample captures page:
   126  	//
   127  	//    https://wiki.wireshark.org/SampleCaptures
   128  	//    https://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=get&target=NTP_sync.pcap
   129  	//
   130  	// This packet was chosen because it is the first NTP packet after the first
   131  	// NTP packet that has non-zero timestamps.
   132  
   133  	var testPacketNTP = []byte{
   134  		0x00, 0xd0, 0x59, 0x6c, 0x40, 0x4e, 0x00, 0x0c,
   135  		0x41, 0x82, 0xb2, 0x53, 0x08, 0x00, 0x45, 0x00,
   136  		0x00, 0x4c, 0x32, 0x46, 0x40, 0x00, 0x2f, 0x11,
   137  		0xa8, 0x18, 0x45, 0x2c, 0x39, 0x3c, 0xc0, 0xa8,
   138  		0x32, 0x32, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x38,
   139  		0x09, 0x58, 0x1a, 0x03, 0x0a, 0xee, 0x00, 0x00,
   140  		0x1b, 0xf7, 0x00, 0x00, 0x14, 0xec, 0x51, 0xae,
   141  		0x80, 0xb7, 0xc5, 0x02, 0x03, 0x4c, 0x8d, 0x0e,
   142  		0x66, 0xcb, 0xc5, 0x02, 0x04, 0xec, 0xec, 0x42,
   143  		0xee, 0x92, 0xc5, 0x02, 0x04, 0xeb, 0xcf, 0x49,
   144  		0x59, 0xe6, 0xc5, 0x02, 0x04, 0xeb, 0xcf, 0x4c,
   145  		0x6e, 0x6e,
   146  	}
   147  
   148  	// Assemble the NTP object that we expect to emerge from this test.
   149  	pExpectedNTP := &NTP{
   150  		BaseLayer: BaseLayer{
   151  			Contents: []byte{0x1a, 0x03, 0x0a, 0xee, 0x00, 0x00,
   152  				0x1b, 0xf7, 0x00, 0x00, 0x14, 0xec, 0x51, 0xae,
   153  				0x80, 0xb7, 0xc5, 0x02, 0x03, 0x4c, 0x8d, 0x0e,
   154  				0x66, 0xcb, 0xc5, 0x02, 0x04, 0xec, 0xec, 0x42,
   155  				0xee, 0x92, 0xc5, 0x02, 0x04, 0xeb, 0xcf, 0x49,
   156  				0x59, 0xe6, 0xc5, 0x02, 0x04, 0xeb, 0xcf, 0x4c,
   157  				0x6e, 0x6e},
   158  			Payload: nil,
   159  		},
   160  		LeapIndicator:      0,
   161  		Version:            3,
   162  		Mode:               2,
   163  		Stratum:            3,
   164  		Poll:               10,
   165  		Precision:          -18,
   166  		RootDelay:          0x1bf7,
   167  		RootDispersion:     0x14ec,
   168  		ReferenceID:        0x51ae80b7,
   169  		ReferenceTimestamp: 0xc502034c8d0e66cb,
   170  		OriginTimestamp:    0xc50204ecec42ee92,
   171  		ReceiveTimestamp:   0xc50204ebcf4959e6,
   172  		TransmitTimestamp:  0xc50204ebcf4c6e6e,
   173  		ExtensionBytes:     []byte{},
   174  	}
   175  
   176  	checkNTP("test02", t, testPacketNTP, pExpectedNTP)
   177  }
   178  
   179  //******************************************************************************
   180  
   181  func TestNTPThree(t *testing.T) {
   182  
   183  	// This test packet is packet #19 in the NTP sample capture
   184  	// pcap file NTP_sync.pcap on the Wireshark sample captures page:
   185  	//
   186  	//    https://wiki.wireshark.org/SampleCaptures
   187  	//    https://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=get&target=NTP_sync.pcap
   188  
   189  	var testPacketNTP = []byte{
   190  		0x00, 0xd0, 0x59, 0x6c, 0x40, 0x4e, 0x00, 0x0c,
   191  		0x41, 0x82, 0xb2, 0x53, 0x08, 0x00, 0x45, 0x00,
   192  		0x00, 0x4c, 0x00, 0x00, 0x40, 0x00, 0x30, 0x11,
   193  		0x74, 0x65, 0x18, 0x7b, 0xca, 0xe6, 0xc0, 0xa8,
   194  		0x32, 0x32, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x38,
   195  		0x44, 0x05, 0x1a, 0x02, 0x0a, 0xec, 0x00, 0x00,
   196  		0x07, 0xc3, 0x00, 0x00, 0x2f, 0x80, 0xc6, 0x1e,
   197  		0x5c, 0x02, 0xc5, 0x01, 0xf9, 0x95, 0x42, 0x50,
   198  		0x82, 0xcf, 0xc5, 0x02, 0x04, 0xec, 0xec, 0x42,
   199  		0xee, 0x92, 0xc5, 0x02, 0x04, 0xeb, 0xd2, 0x35,
   200  		0x2e, 0xb5, 0xc5, 0x02, 0x04, 0xeb, 0xd2, 0x35,
   201  		0xd6, 0x7b,
   202  	}
   203  
   204  	// Assemble the NTP object that we expect to emerge from this test.
   205  	pExpectedNTP := &NTP{
   206  		BaseLayer: BaseLayer{
   207  			Contents: []byte{0x1a, 0x02, 0x0a, 0xec, 0x00, 0x00,
   208  				0x07, 0xc3, 0x00, 0x00, 0x2f, 0x80, 0xc6, 0x1e,
   209  				0x5c, 0x02, 0xc5, 0x01, 0xf9, 0x95, 0x42, 0x50,
   210  				0x82, 0xcf, 0xc5, 0x02, 0x04, 0xec, 0xec, 0x42,
   211  				0xee, 0x92, 0xc5, 0x02, 0x04, 0xeb, 0xd2, 0x35,
   212  				0x2e, 0xb5, 0xc5, 0x02, 0x04, 0xeb, 0xd2, 0x35,
   213  				0xd6, 0x7b},
   214  			Payload: nil,
   215  		},
   216  		LeapIndicator:      0,
   217  		Version:            3,
   218  		Mode:               2,
   219  		Stratum:            2,
   220  		Poll:               10,
   221  		Precision:          -20,
   222  		RootDelay:          0x7c3,
   223  		RootDispersion:     0x2f80,
   224  		ReferenceID:        0xc61e5c02,
   225  		ReferenceTimestamp: 0xc501f995425082cf,
   226  		OriginTimestamp:    0xc50204ecec42ee92,
   227  		ReceiveTimestamp:   0xc50204ebd2352eb5,
   228  		TransmitTimestamp:  0xc50204ebd235d67b,
   229  		ExtensionBytes:     []byte{},
   230  	}
   231  
   232  	checkNTP("test03", t, testPacketNTP, pExpectedNTP)
   233  }
   234  
   235  //******************************************************************************
   236  
   237  // TestNTPIsomorphism tests whether random data gets parsed into NTP layer and
   238  // gets serialized back from it to the same value.
   239  func TestNTPIsomorphism(t *testing.T) {
   240  	NTPData := make([]byte, ntpMinimumRecordSizeInBytes+7)
   241  	_, err := io.ReadFull(rand.Reader, NTPData)
   242  	if err != nil {
   243  		t.Error(err)
   244  	}
   245  	ntpLayer := &NTP{}
   246  	err = ntpLayer.DecodeFromBytes(NTPData, gopacket.NilDecodeFeedback)
   247  	if err != nil {
   248  		t.Error(err)
   249  	}
   250  	buf := gopacket.NewSerializeBuffer()
   251  	opts := gopacket.SerializeOptions{}
   252  	err = ntpLayer.SerializeTo(buf, opts)
   253  	if err != nil {
   254  		t.Error(err)
   255  	}
   256  	if !reflect.DeepEqual(NTPData, buf.Bytes()) {
   257  		t.Errorf("NTP packet is not isomorphic:\ngot  :\n%x\n\nwant :\n%x\n\n", buf.Bytes(), NTPData)
   258  	}
   259  }