func InitEmptyIPv6Packet(packet *Packet, plSize uint) bool {
	bufSize := plSize + types.EtherLen + types.IPv6Len
	if low.AppendMbuf(packet.CMbuf, bufSize) == false {
		LogWarning(Debug, "InitEmptyIPv6Packet: Cannot append mbuf")
		return false
	}
	packet.Ether.EtherType = SwapBytesUint16(types.IPV6Number)
	packet.Data = unsafe.Pointer(uintptr(packet.unparsed()) + types.IPv6Len)
	packet.ParseL3()
	fillIPv6Default(packet, uint16(plSize), types.NoNextHeader)
	return true
}
InitEmptyIPv6Packet initializes input packet with preallocated plSize of bytes for payload
and init pointers to Ethernet and IPv6 headers.
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
}
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
}
func InitNextPacket(plSize uint, prev *Packet) *Packet {
	packet, err := NewPacket()
	if err != nil || low.AppendMbuf(packet.CMbuf, plSize) == false {
		LogWarning(Debug, "InitNextPacket: Cannot allocate new packet")
		return nil
	}
	packet.Data = unsafe.Pointer(packet.Ether)
	prev.Next = packet
	low.SetNextMbuf(packet.CMbuf, prev.CMbuf)
	return packet
}
func fillIPv4Default(packet *Packet, plLen uint16, nextProto uint8) {
	packet.GetIPv4NoCheck().VersionIhl = types.IPv4VersionIhl
	packet.GetIPv4NoCheck().TotalLength = SwapBytesUint16(plLen)
	packet.GetIPv4NoCheck().NextProtoID = nextProto
	packet.GetIPv4NoCheck().TimeToLive = 64
}
func fillIPv6Default(packet *Packet, totalLen uint16, nextProto uint8) {
	packet.GetIPv6NoCheck().PayloadLen = SwapBytesUint16(totalLen)
	packet.GetIPv6NoCheck().VtcFlow = types.IPv6VtcFlow
	packet.GetIPv6NoCheck().Proto = nextProto
	packet.GetIPv6NoCheck().HopLimits = 255
}
func InitEmptyIPv4Packet(packet *Packet, plSize uint) bool {
	bufSize := plSize + types.EtherLen + types.IPv4MinLen
	if low.AppendMbuf(packet.CMbuf, bufSize) == false {
		LogWarning(Debug, "InitEmptyIPv4Packet: Cannot append mbuf")
		return false
	}
	packet.Ether.EtherType = SwapBytesUint16(types.IPV4Number)
	packet.Data = unsafe.Pointer(uintptr(packet.unparsed()) + types.IPv4MinLen)
	packet.ParseL3()
	fillIPv4Default(packet, uint16(types.IPv4MinLen+plSize), types.NoNextHeader)
	if hwtxchecksum {
		packet.GetIPv4NoCheck().HdrChecksum = 0
		low.SetTXIPv4OLFlags(packet.CMbuf, types.EtherLen, types.IPv4MinLen)
	}
	return true
}