Permalink
Browse files

Implement SerializeTo() for NTP layer

  • Loading branch information...
nogoegst authored and gconnell committed May 3, 2017
1 parent a9784fc commit b0b789be7511f047cf2cf6bf9ef61bf83ebfb8c3
Showing with 74 additions and 1 deletion.
  1. +37 −0 layers/ntp.go
  2. +37 −1 layers/ntp_test.go
@@ -347,6 +347,43 @@ func (d *NTP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
return nil
}
// SerializeTo writes the serialized form of this layer into the
// SerializationBuffer, implementing gopacket.SerializableLayer.
// See the docs for gopacket.SerializableLayer for more info.
func (d *NTP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
data, err := b.PrependBytes(ntpMinimumRecordSizeInBytes)
if err != nil {
return err
}
// Pack the first few fields into the first 32 bits.
h := uint32(0)
h |= (uint32(d.LeapIndicator) << 30) & 0xC0000000
h |= (uint32(d.Version) << 27) & 0x38000000
h |= (uint32(d.Mode) << 24) & 0x07000000
h |= (uint32(d.Stratum) << 16) & 0x00FF0000
h |= (uint32(d.Poll) << 8) & 0x0000FF00
h |= (uint32(d.Precision) << 0) & 0x000000FF
binary.BigEndian.PutUint32(data[0:4], h)
// The remaining fields can just be copied in big endian order.
binary.BigEndian.PutUint32(data[4:8], uint32(d.RootDelay))
binary.BigEndian.PutUint32(data[8:12], uint32(d.RootDispersion))
binary.BigEndian.PutUint32(data[12:16], uint32(d.ReferenceID))
binary.BigEndian.PutUint64(data[16:24], uint64(d.ReferenceTimestamp))
binary.BigEndian.PutUint64(data[24:32], uint64(d.OriginTimestamp))
binary.BigEndian.PutUint64(data[32:40], uint64(d.ReceiveTimestamp))
binary.BigEndian.PutUint64(data[40:48], uint64(d.TransmitTimestamp))
ex, err := b.AppendBytes(len(d.ExtensionBytes))
if err != nil {
return err
}
copy(ex, d.ExtensionBytes)
return nil
}
//******************************************************************************
// CanDecode returns a set of layers that NTP objects can decode.
@@ -9,7 +9,9 @@
package layers
import (
"crypto/rand"
"github.com/google/gopacket"
"io"
"reflect"
"testing"
)
@@ -18,7 +20,7 @@ import (
// checkNTP() uses the ntp.go code to analyse the packet bytes as an NTP UDP
// packet and generate an NTP object. It then compares the generated NTP object
// with the one provided and raises the alarm if there is any difference.
// with the one provided and throws an error if there is any difference.
// The desc argument is output with any failure message to identify the test.
func checkNTP(desc string, t *testing.T, packetBytes []byte, pExpectedNTP *NTP) {
@@ -50,6 +52,16 @@ func checkNTP(desc string, t *testing.T, packetBytes []byte, pExpectedNTP *NTP)
t.Errorf("NTP packet processing failed for packet "+desc+
":\ngot :\n%#v\n\nwant :\n%#v\n\n", pResultNTP, pExpectedNTP)
}
buf := gopacket.NewSerializeBuffer()
opts := gopacket.SerializeOptions{}
err := pResultNTP.SerializeTo(buf, opts)
if err != nil {
t.Error(err)
}
if !reflect.DeepEqual(pResultNTP.BaseLayer.Contents, buf.Bytes()) {
t.Errorf("NTP packet serialization failed for packet "+desc+
":\ngot :\n%x\n\nwant :\n%x\n\n", buf.Bytes(), packetBytes)
}
}
//******************************************************************************
@@ -220,3 +232,27 @@ func TestNTPThree(t *testing.T) {
}
//******************************************************************************
// TestNTPIsomorphism tests whether random data gets parsed into NTP layer and
// gets serialized back from it to the same value.
func TestNTPIsomorphism(t *testing.T) {
NTPData := make([]byte, ntpMinimumRecordSizeInBytes+7)
_, err := io.ReadFull(rand.Reader, NTPData)
if err != nil {
t.Error(err)
}
ntpLayer := &NTP{}
err = ntpLayer.DecodeFromBytes(NTPData, gopacket.NilDecodeFeedback)
if err != nil {
t.Error(err)
}
buf := gopacket.NewSerializeBuffer()
opts := gopacket.SerializeOptions{}
err = ntpLayer.SerializeTo(buf, opts)
if err != nil {
t.Error(err)
}
if !reflect.DeepEqual(NTPData, buf.Bytes()) {
t.Errorf("NTP packet is not isomorphic:\ngot :\n%x\n\nwant :\n%x\n\n", buf.Bytes(), NTPData)
}
}

0 comments on commit b0b789b

Please sign in to comment.