[VOL-1349] EPON OLT adapter (package B)

Change-Id: I634ef62c53813dcf4456f54948f13e06358e263c
diff --git a/vendor/github.com/google/gopacket/layers/gtp.go b/vendor/github.com/google/gopacket/layers/gtp.go
new file mode 100644
index 0000000..0ec8a6a
--- /dev/null
+++ b/vendor/github.com/google/gopacket/layers/gtp.go
@@ -0,0 +1,181 @@
+// Copyright 2017 Google, Inc. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree.
+//
+
+package layers
+
+import (
+	"encoding/binary"
+	"fmt"
+	"github.com/google/gopacket"
+)
+
+const gtpMinimumSizeInBytes int = 8
+
+// GTPExtensionHeader is used to carry extra data and enable future extensions of the GTP  without the need to use another version number.
+type GTPExtensionHeader struct {
+	Type    uint8
+	Content []byte
+}
+
+// GTPv1U protocol is used to exchange user data over GTP tunnels across the Sx interfaces.
+// Defined in https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1595
+type GTPv1U struct {
+	BaseLayer
+	Version             uint8
+	ProtocolType        uint8
+	Reserved            uint8
+	ExtensionHeaderFlag bool
+	SequenceNumberFlag  bool
+	NPDUFlag            bool
+	MessageType         uint8
+	MessageLength       uint16
+	TEID                uint32
+	SequenceNumber      uint16
+	NPDU                uint8
+	GTPExtensionHeaders []GTPExtensionHeader
+}
+
+// LayerType returns LayerTypeGTPV1U
+func (g *GTPv1U) LayerType() gopacket.LayerType { return LayerTypeGTPv1U }
+
+// DecodeFromBytes analyses a byte slice and attempts to decode it as a GTPv1U packet
+func (g *GTPv1U) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
+	hLen := gtpMinimumSizeInBytes
+	dLen := len(data)
+	if dLen < hLen {
+		return fmt.Errorf("GTP packet too small: %d bytes", dLen)
+	}
+	g.Version = (data[0] >> 5) & 0x07
+	g.ProtocolType = (data[0] >> 4) & 0x01
+	g.Reserved = (data[0] >> 3) & 0x01
+	g.SequenceNumberFlag = ((data[0] >> 1) & 0x01) == 1
+	g.NPDUFlag = (data[0] & 0x01) == 1
+	g.ExtensionHeaderFlag = ((data[0] >> 2) & 0x01) == 1
+	g.MessageType = data[1]
+	g.MessageLength = binary.BigEndian.Uint16(data[2:4])
+	pLen := 8 + g.MessageLength
+	if uint16(dLen) < pLen {
+		return fmt.Errorf("GTP packet too small: %d bytes", dLen)
+	}
+	//  Field used to multiplex different connections in the same GTP tunnel.
+	g.TEID = binary.BigEndian.Uint32(data[4:8])
+	cIndex := uint16(hLen)
+	if g.SequenceNumberFlag || g.NPDUFlag || g.ExtensionHeaderFlag {
+		hLen += 4
+		cIndex += 4
+		if dLen < hLen {
+			return fmt.Errorf("GTP packet too small: %d bytes", dLen)
+		}
+		if g.SequenceNumberFlag {
+			g.SequenceNumber = binary.BigEndian.Uint16(data[8:10])
+		}
+		if g.NPDUFlag {
+			g.NPDU = data[10]
+		}
+		if g.ExtensionHeaderFlag {
+			extensionFlag := true
+			for extensionFlag {
+				extensionType := uint8(data[cIndex-1])
+				extensionLength := uint(data[cIndex])
+				if extensionLength == 0 {
+					return fmt.Errorf("GTP packet with invalid extension header")
+				}
+				// extensionLength is in 4-octet units
+				lIndex := cIndex + (uint16(extensionLength) * 4)
+				if uint16(dLen) < lIndex {
+					fmt.Println(dLen, lIndex)
+					return fmt.Errorf("GTP packet with small extension header: %d bytes", dLen)
+				}
+				content := data[cIndex+1 : lIndex-1]
+				eh := GTPExtensionHeader{Type: extensionType, Content: content}
+				g.GTPExtensionHeaders = append(g.GTPExtensionHeaders, eh)
+				cIndex = lIndex
+				// Check if coming bytes are from an extension header
+				extensionFlag = data[cIndex-1] != 0
+
+			}
+		}
+	}
+	g.BaseLayer = BaseLayer{Contents: data[:cIndex], Payload: data[cIndex:]}
+	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 (g *GTPv1U) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+	data, err := b.PrependBytes(gtpMinimumSizeInBytes)
+	if err != nil {
+		return err
+	}
+	data[0] |= (g.Version << 5)
+	data[0] |= (1 << 4)
+	if len(g.GTPExtensionHeaders) > 0 {
+		data[0] |= 0x04
+		g.ExtensionHeaderFlag = true
+	}
+	if g.SequenceNumberFlag {
+		data[0] |= 0x02
+	}
+	if g.NPDUFlag {
+		data[0] |= 0x01
+	}
+	data[1] = g.MessageType
+	binary.BigEndian.PutUint16(data[2:4], g.MessageLength)
+	binary.BigEndian.PutUint32(data[4:8], g.TEID)
+	if g.ExtensionHeaderFlag || g.SequenceNumberFlag || g.NPDUFlag {
+		data, err := b.AppendBytes(4)
+		if err != nil {
+			return err
+		}
+		binary.BigEndian.PutUint16(data[:2], g.SequenceNumber)
+		data[2] = g.NPDU
+		for _, eh := range g.GTPExtensionHeaders {
+			data[len(data)-1] = eh.Type
+			lContent := len(eh.Content)
+			// extensionLength is in 4-octet units
+			extensionLength := (lContent + 2) / 4
+			// Get two extra byte for the next extension header type and length
+			data, err = b.AppendBytes(lContent + 2)
+			if err != nil {
+				return err
+			}
+			data[0] = byte(extensionLength)
+			copy(data[1:lContent+1], eh.Content)
+		}
+	}
+	return nil
+
+}
+
+// CanDecode returns a set of layers that GTP objects can decode.
+func (g *GTPv1U) CanDecode() gopacket.LayerClass {
+	return LayerTypeGTPv1U
+}
+
+// NextLayerType specifies the next layer that GoPacket should attempt to
+func (g *GTPv1U) NextLayerType() gopacket.LayerType {
+	version := uint8(g.LayerPayload()[0]) >> 4
+	if version == 4 {
+		return LayerTypeIPv4
+	} else if version == 6 {
+		return LayerTypeIPv6
+	} else {
+		return LayerTypePPP
+	}
+}
+
+func decodeGTPv1u(data []byte, p gopacket.PacketBuilder) error {
+	gtp := &GTPv1U{}
+	err := gtp.DecodeFromBytes(data, p)
+	if err != nil {
+		return err
+	}
+	p.AddLayer(gtp)
+	return p.NextDecoder(gtp.NextLayerType())
+}