func (packet *Packet) DecapsulateIPv4GTP() bool {
	if !packet.DecapsulateHead(EtherLen, IPv4MinLen+UDPLen+GTPMinLen) {
		return false
	}
	return true
}
DecapsulateIPv4GTP assumes that user has etherNet->IPv4->UDP->GTP->payload data structure
with standart IPv4 header size and wants to leave only ether->payload part
It is also assumed that payload is encapsulated IPv4 datagram, so no etherType changes are needed
package packet
import (
	"fmt"
	"unsafe"
	. "github.com/intel-go/nff-go/types"
)
type GTPHdr struct {
	HeaderType          uint8  
	MessageType         uint8
	MessageLength       uint16
	TEID                uint32
	SequenceNumber      uint16  
	NPDUNumber          uint8   
	NextExtensionHeader uint8   
}
const (
	NoExtensionHeaders             = 0x00
	UDPPortExtensionHeader         = 0x40
	PDCP_PDU_NumberExtensionHeader = 0xc0
)
type UDPPort struct {
	Length              uint8  
	UDPPortNumber       uint16
	NextExtensionHeader uint8
}
type PDCP_PDU_Number struct {
	Length              uint8  
	PDCP_PDU_Number_1   uint8
	PDCP_PDU_Number_2   uint8
	NextExtensionHeader uint8
}
const (
	EchoRequest                           = 1
	EchoResponse                          = 2
	SupportedExtensionHeadersNotification = 31
	ErrorIndication = 26
	EndMarker       = 254
	G_PDU = 255
	UDPPortGTPU     = 2152
	SwapUDPPortGTPU = 26632
)
func (hdr *GTPHdr) String() string {
	hType := "GTPv1"
	hTypeType := "GTP"
	if hdr.HeaderType&0xe0 != 1 {
		hType = "not GTPv1"  
	}
	if hdr.HeaderType&0x10 == 0 {
		hTypeType = "GTP'"
	}
	min := fmt.Sprintf(`%s (%s): Message type: %d, Message length: %d, TEID: %d`, hTypeType, hType,
		hdr.MessageType, SwapBytesUint16(hdr.MessageLength), SwapBytesUint32(hdr.TEID))
	if hdr.HeaderType&0x02 != 0 {
		min += fmt.Sprintf(`, Sequence number %d`, SwapBytesUint16(hdr.SequenceNumber))
	}
	if hdr.HeaderType&0x01 != 0 {
		min += fmt.Sprintf(`, N-PDU number %d`, hdr.NPDUNumber)
	}
	if hdr.HeaderType&0x04 != 0 {
		min += fmt.Sprintf(`, N-PDU number %d`, hdr.NextExtensionHeader)
	}
	min += "\n"
	return min
}
func (packet *Packet) GetGTP() *GTPHdr {
	return (*GTPHdr)(packet.Data)
}
func (packet *Packet) GTPIPv4FastParsing() *GTPHdr {
	return (*GTPHdr)(unsafe.Pointer(uintptr(packet.unparsed()) + IPv4MinLen + UDPLen))
}
func (packet *Packet) GTPIPv4AllParsing() *GTPHdr {
	packet.ParseL3()
	packet.ParseL4ForIPv4()
	packet.ParseL7(UDPNumber)
	return packet.GetGTP()
}
func (packet *Packet) EncapsulateIPv4GTP(TEID uint32) bool {
	length := packet.GetPacketLen() - EtherLen
	if !packet.EncapsulateHead(EtherLen, IPv4MinLen+UDPLen+GTPMinLen) {
		return false
	}
	gtp := (*GTPHdr)(unsafe.Pointer(uintptr(packet.unparsed()) + IPv4MinLen + UDPLen))
	gtp.HeaderType = 0x30    
	gtp.MessageType = G_PDU  
	gtp.MessageLength = SwapBytesUint16(uint16(length))
	gtp.TEID = SwapBytesUint32(TEID)
	return true
}