func InitEmptyPacket(packet *Packet, plSize uint) bool {
	bufSize := plSize + types.EtherLen
	if low.AppendMbuf(packet.CMbuf, bufSize) == false {
		LogWarning(Debug, "InitEmptyPacket: Cannot append mbuf")
		return false
	}
	packet.Data = packet.unparsed()
	return true
}
All following functions set Data pointer because it is assumed that user
need to generate real packets with some information.
InitEmptyPacket initializes input packet with preallocated plSize of bytes for payload
and init pointer to Ethernet header.
package packet
import (
	"fmt"
	"unsafe"
	. "github.com/intel-go/nff-go/common"
	"github.com/intel-go/nff-go/internal/low"
	"github.com/intel-go/nff-go/types"
)
var mbufStructSize uintptr
var hwtxchecksum bool
var nonPerfMempool *low.Mempool
func init() {
	var t1 low.Mbuf
	mbufStructSize = unsafe.Sizeof(t1)
	var t2 Packet
	packetStructSize := unsafe.Sizeof(t2)
	if err := low.SetPacketStructSize(int(packetStructSize)); err != nil {
		LogFatal(Debug, err)
	}
}
type EtherHdr struct {
	DAddr     types.MACAddress  
	SAddr     types.MACAddress  
	EtherType uint16            
}
func (hdr *EtherHdr) String() string {
	return fmt.Sprintf(`L2 protocol: Ethernet, EtherType: 0x%04x (%s)
Ethernet Source: %s
Ethernet Destination: %s
`,
		hdr.EtherType, getEtherTypeName(hdr.EtherType),
		hdr.SAddr.String(),
		hdr.DAddr.String())
}
var (
	etherTypeNameLookupTable = map[uint16]string{
		types.SwapIPV4Number: "IPv4",
		types.SwapARPNumber:  "ARP",
		types.SwapVLANNumber: "VLAN",
		types.SwapMPLSNumber: "MPLS",
		types.SwapIPV6Number: "IPv6",
	}
)
func getEtherTypeName(et uint16) string {
	ret, ok := etherTypeNameLookupTable[et]
	if !ok {
		return "unknown"
	}
	return ret
}
type IPv4Hdr struct {
	VersionIhl     uint8              
	TypeOfService  uint8              
	TotalLength    uint16             
	PacketID       uint16             
	FragmentOffset uint16             
	TimeToLive     uint8              
	NextProtoID    uint8              
	HdrChecksum    uint16             
	SrcAddr        types.IPv4Address  
	DstAddr        types.IPv4Address  
}
func (hdr *IPv4Hdr) String() string {
	r0 := "    L3 protocol: IPv4\n"
	r1 := "    IPv4 Source: " + hdr.SrcAddr.String() + "\n"
	r2 := "    IPv4 Destination: " + hdr.DstAddr.String() + "\n"
	return r0 + r1 + r2
}
type IPv6Hdr struct {
	VtcFlow    uint32             
	PayloadLen uint16             
	Proto      uint8              
	HopLimits  uint8              
	SrcAddr    types.IPv6Address  
	DstAddr    types.IPv6Address  
}
func (hdr *IPv6Hdr) String() string {
	return fmt.Sprintf(`    L3 protocol: IPv6
    IPv6 Source: %s
    IPv6 Destination %s
`, hdr.SrcAddr.String(), hdr.DstAddr.String())
}
type TCPHdr struct {
	SrcPort  uint16          
	DstPort  uint16          
	SentSeq  uint32          
	RecvAck  uint32          
	DataOff  uint8           
	TCPFlags types.TCPFlags  
	RxWin    uint16          
	Cksum    uint16          
	TCPUrp   uint16          
}
func (hdr *TCPHdr) String() string {
	r0 := "        L4 protocol: TCP\n"
	r1 := fmt.Sprintf("        L4 Source: %d\n", SwapBytesUint16(hdr.SrcPort))
	r2 := fmt.Sprintf("        L4 Destination: %d\n", SwapBytesUint16(hdr.DstPort))
	return r0 + r1 + r2
}
type UDPHdr struct {
	SrcPort    uint16  
	DstPort    uint16  
	DgramLen   uint16  
	DgramCksum uint16  
}
func (hdr *UDPHdr) String() string {
	r0 := "        L4 protocol: UDP\n"
	r1 := fmt.Sprintf("        L4 Source: %d\n", SwapBytesUint16(hdr.SrcPort))
	r2 := fmt.Sprintf("        L4 Destination: %d\n", SwapBytesUint16(hdr.DstPort))
	return r0 + r1 + r2
}
type ICMPHdr struct {
	Type       uint8   
	Code       uint8   
	Cksum      uint16  
	Identifier uint16  
	SeqNum     uint16  
}
func (hdr *ICMPHdr) String() string {
	r0 := "        L4 protocol: ICMP\n"
	r1 := fmt.Sprintf("        ICMP Type: %d\n", hdr.Type)
	r2 := fmt.Sprintf("        ICMP Code: %d\n", hdr.Code)
	r3 := fmt.Sprintf("        ICMP Cksum: %d\n", SwapBytesUint16(hdr.Cksum))
	r4 := fmt.Sprintf("        ICMP Identifier: %d\n", SwapBytesUint16(hdr.Identifier))
	r5 := fmt.Sprintf("        ICMP SeqNum: %d\n", SwapBytesUint16(hdr.SeqNum))
	return r0 + r1 + r2 + r3 + r4 + r5
}
type Packet struct {
	L3   unsafe.Pointer  
	L4   unsafe.Pointer  
	Data unsafe.Pointer  
	Ether *EtherHdr  
	CMbuf *low.Mbuf  
	Next *Packet  
}
func (packet *Packet) unparsed() unsafe.Pointer {
	ether := unsafe.Pointer(packet.Ether)
	return unsafe.Pointer(uintptr(ether) + types.EtherLen)
}
func (packet *Packet) StartAtOffset(offset uintptr) unsafe.Pointer {
	start := unsafe.Pointer(packet.Ether)
	return unsafe.Pointer(uintptr(start) + offset)
}
func (packet *Packet) ParseL3() {
	packet.L3 = packet.unparsed()
}
func (packet *Packet) GetIPv4() *IPv4Hdr {
	if packet.Ether.EtherType == SwapBytesUint16(types.IPV4Number) {
		return (*IPv4Hdr)(packet.L3)
	}
	return nil
}
func (packet *Packet) GetIPv4NoCheck() *IPv4Hdr {
	return (*IPv4Hdr)(packet.L3)
}
func (packet *Packet) GetARP() *ARPHdr {
	if packet.Ether.EtherType == SwapBytesUint16(types.ARPNumber) {
		return (*ARPHdr)(packet.L3)
	}
	return nil
}
func (packet *Packet) GetARPNoCheck() *ARPHdr {
	return (*ARPHdr)(packet.L3)
}
func (packet *Packet) GetIPv6() *IPv6Hdr {
	if packet.Ether.EtherType == SwapBytesUint16(types.IPV6Number) {
		return (*IPv6Hdr)(packet.L3)
	}
	return nil
}
func (packet *Packet) GetIPv6NoCheck() *IPv6Hdr {
	return (*IPv6Hdr)(packet.L3)
}
func (packet *Packet) ParseL4ForIPv4() {
	packet.L4 = unsafe.Pointer(uintptr(packet.L3) + uintptr((packet.GetIPv4NoCheck().VersionIhl&0x0f)<<2))
}
func (packet *Packet) ParseL4ForIPv6() {
	packet.L4 = unsafe.Pointer(uintptr(packet.L3) + uintptr(types.IPv6Len))
}
func (packet *Packet) GetTCPForIPv4() *TCPHdr {
	if packet.GetIPv4NoCheck().NextProtoID == types.TCPNumber {
		return (*TCPHdr)(packet.L4)
	}
	return nil
}
func (packet *Packet) GetTCPNoCheck() *TCPHdr {
	return (*TCPHdr)(packet.L4)
}
func (packet *Packet) GetTCPForIPv6() *TCPHdr {
	if packet.GetIPv6NoCheck().Proto == types.TCPNumber {
		return (*TCPHdr)(packet.L4)
	}
	return nil
}
func (packet *Packet) GetUDPForIPv4() *UDPHdr {
	if packet.GetIPv4NoCheck().NextProtoID == types.UDPNumber {
		return (*UDPHdr)(packet.L4)
	}
	return nil
}
func (packet *Packet) GetUDPNoCheck() *UDPHdr {
	return (*UDPHdr)(packet.L4)
}
func (packet *Packet) GetUDPForIPv6() *UDPHdr {
	if packet.GetIPv6NoCheck().Proto == types.UDPNumber {
		return (*UDPHdr)(packet.L4)
	}
	return nil
}
func (packet *Packet) GetICMPForIPv4() *ICMPHdr {
	if packet.GetIPv4NoCheck().NextProtoID == types.ICMPNumber {
		return (*ICMPHdr)(packet.L4)
	}
	return nil
}
func (packet *Packet) GetICMPNoCheck() *ICMPHdr {
	return (*ICMPHdr)(packet.L4)
}
func (packet *Packet) GetICMPForIPv6() *ICMPHdr {
	if packet.GetIPv6NoCheck().Proto == types.ICMPv6Number {
		return (*ICMPHdr)(packet.L4)
	}
	return nil
}
func (packet *Packet) ParseAllKnownL3() (*IPv4Hdr, *IPv6Hdr, *ARPHdr) {
	packet.ParseL3()
	if packet.GetIPv4() != nil {
		return packet.GetIPv4NoCheck(), nil, nil
	} else if packet.GetIPv6() != nil {
		return nil, packet.GetIPv6NoCheck(), nil
	} else if packet.GetARP() != nil {
		return nil, nil, packet.GetARPNoCheck()
	}
	return nil, nil, nil
}
func (packet *Packet) ParseAllKnownL4ForIPv4() (*TCPHdr, *UDPHdr, *ICMPHdr) {
	packet.ParseL4ForIPv4()
	if packet.GetTCPForIPv4() != nil {
		return packet.GetTCPNoCheck(), nil, nil
	} else if packet.GetUDPForIPv4() != nil {
		return nil, packet.GetUDPNoCheck(), nil
	} else if packet.GetICMPForIPv4() != nil {
		return nil, nil, packet.GetICMPNoCheck()
	}
	return nil, nil, nil
}
func (packet *Packet) ParseAllKnownL4ForIPv6() (*TCPHdr, *UDPHdr, *ICMPHdr) {
	packet.ParseL4ForIPv6()
	if packet.GetTCPForIPv6() != nil {
		return packet.GetTCPNoCheck(), nil, nil
	} else if packet.GetUDPForIPv6() != nil {
		return nil, packet.GetUDPNoCheck(), nil
	} else if packet.GetICMPForIPv6() != nil {
		return nil, nil, packet.GetICMPNoCheck()
	}
	return nil, nil, nil
}
func (packet *Packet) ParseL7(protocol uint) {
	switch protocol {
	case types.TCPNumber:
		packet.Data = unsafe.Pointer(uintptr(packet.L4) + uintptr(((*TCPHdr)(packet.L4)).DataOff&0xf0)>>2)
	case types.UDPNumber:
		packet.Data = unsafe.Pointer(uintptr(packet.L4) + uintptr(types.UDPLen))
	case types.ICMPNumber:
		fallthrough
	case types.ICMPv6Number:
		packet.Data = unsafe.Pointer(uintptr(packet.L4) + uintptr(types.ICMPLen))
	}
}
func (packet *Packet) ParseData() int {
	var pktTCP *TCPHdr
	var pktUDP *UDPHdr
	var pktICMP *ICMPHdr
	pktIPv4, pktIPv6, _ := packet.ParseAllKnownL3()
	if pktIPv4 != nil {
		pktTCP, pktUDP, pktICMP = packet.ParseAllKnownL4ForIPv4()
	} else if pktIPv6 != nil {
		pktTCP, pktUDP, pktICMP = packet.ParseAllKnownL4ForIPv6()
	}
	if pktTCP != nil {
		packet.Data = unsafe.Pointer(uintptr(packet.L4) + uintptr(((*TCPHdr)(packet.L4)).DataOff&0xf0)>>2)
	} else if pktUDP != nil {
		packet.Data = unsafe.Pointer(uintptr(packet.L4) + uintptr(types.UDPLen))
	} else if pktICMP != nil {
		packet.Data = unsafe.Pointer(uintptr(packet.L4) + uintptr(types.ICMPLen))
	} else {
		return -1
	}
	return 0
}
func ExtractPacketAddr(IN uintptr) uintptr {
	return IN + mbufStructSize
}
func ToPacket(IN uintptr) *Packet {
	return (*Packet)(unsafe.Pointer(IN))
}
func ExtractPacket(IN uintptr) *Packet {
	return ToPacket(ExtractPacketAddr(IN))
}
func SetHWTXChecksumFlag(flag bool) {
	hwtxchecksum = flag
}
func ExtractPackets(packet []*Packet, IN []uintptr, n uint) {
	for i := uint(0); i < n; i++ {
		packet[i] = ExtractPacket(IN[i])
	}
}
func (p *Packet) ToUintptr() uintptr {
	return uintptr(unsafe.Pointer(p.CMbuf))
}
func GeneratePacketFromByte(packet *Packet, data []byte) bool {
	if low.AppendMbuf(packet.CMbuf, uint(len(data))) == false {
		LogWarning(Debug, "GeneratePacketFromByte: Cannot append mbuf")
		return false
	}
	low.WriteDataToMbuf(packet.CMbuf, data)
	return true
}