func ConcatFinitePacketDataSources(pds ...PacketDataSource) PacketDataSource {
	c := concat(pds)
	return &c
}
ConcatFinitePacketDataSources returns a PacketDataSource that wraps a set
of internal PacketDataSources, each of which will stop with io.EOF after
reading a finite number of packets.  The returned PacketDataSource will
return all packets from the first finite source, followed by all packets from
the second, etc.  Once all finite sources have returned io.EOF, the returned
source will as well.
package gopacket
import (
	"bytes"
	"encoding/hex"
	"errors"
	"fmt"
	"io"
	"net"
	"os"
	"reflect"
	"runtime/debug"
	"strings"
	"syscall"
	"time"
)
type CaptureInfo struct {
	Timestamp time.Time
	CaptureLength int
	Length int
	InterfaceIndex int
	AncillaryData []interface{}
}
type PacketMetadata struct {
	CaptureInfo
	Truncated bool
}
type Packet interface {
	String() string
	Dump() string
	Layers() []Layer
	Layer(LayerType) Layer
	LayerClass(LayerClass) Layer
	LinkLayer() LinkLayer
	NetworkLayer() NetworkLayer
	TransportLayer() TransportLayer
	ApplicationLayer() ApplicationLayer
	ErrorLayer() ErrorLayer
	Data() []byte
	Metadata() *PacketMetadata
}
type packet struct {
	data []byte
	initialLayers [6]Layer
	layers []Layer
	last Layer
	metadata PacketMetadata
	decodeOptions DecodeOptions
	link        LinkLayer
	network     NetworkLayer
	transport   TransportLayer
	application ApplicationLayer
	failure     ErrorLayer
}
func (p *packet) SetTruncated() {
	p.metadata.Truncated = true
}
func (p *packet) SetLinkLayer(l LinkLayer) {
	if p.link == nil {
		p.link = l
	}
}
func (p *packet) SetNetworkLayer(l NetworkLayer) {
	if p.network == nil {
		p.network = l
	}
}
func (p *packet) SetTransportLayer(l TransportLayer) {
	if p.transport == nil {
		p.transport = l
	}
}
func (p *packet) SetApplicationLayer(l ApplicationLayer) {
	if p.application == nil {
		p.application = l
	}
}
func (p *packet) SetErrorLayer(l ErrorLayer) {
	if p.failure == nil {
		p.failure = l
	}
}
func (p *packet) AddLayer(l Layer) {
	p.layers = append(p.layers, l)
	p.last = l
}
func (p *packet) DumpPacketData() {
	fmt.Fprint(os.Stderr, p.packetDump())
	os.Stderr.Sync()
}
func (p *packet) Metadata() *PacketMetadata {
	return &p.metadata
}
func (p *packet) Data() []byte {
	return p.data
}
func (p *packet) DecodeOptions() *DecodeOptions {
	return &p.decodeOptions
}
func (p *packet) addFinalDecodeError(err error, stack []byte) {
	fail := &DecodeFailure{err: err, stack: stack}
	if p.last == nil {
		fail.data = p.data
	} else {
		fail.data = p.last.LayerPayload()
	}
	p.AddLayer(fail)
	p.SetErrorLayer(fail)
}
func (p *packet) recoverDecodeError() {
	if !p.decodeOptions.SkipDecodeRecovery {
		if r := recover(); r != nil {
			p.addFinalDecodeError(fmt.Errorf("%v", r), debug.Stack())
		}
	}
}
func LayerString(l Layer) string {
	return fmt.Sprintf("%v\t%s", l.LayerType(), layerString(reflect.ValueOf(l), false, false))
}
type Dumper interface {
	Dump() string
}
func LayerDump(l Layer) string {
	var b bytes.Buffer
	b.WriteString(LayerString(l))
	b.WriteByte('\n')
	if d, ok := l.(Dumper); ok {
		dump := d.Dump()
		if dump != "" {
			b.WriteString(dump)
			if dump[len(dump)-1] != '\n' {
				b.WriteByte('\n')
			}
		}
	}
	b.WriteString(hex.Dump(l.LayerContents()))
	return b.String()
}
func layerString(v reflect.Value, anonymous bool, writeSpace bool) string {
	if v.CanInterface() {
		if s, ok := v.Interface().(fmt.Stringer); ok {
			return s.String()
		}
	}
	switch v.Type().Kind() {
	case reflect.Interface, reflect.Ptr:
		if v.IsNil() {
			return "nil"
		}
		r := v.Elem()
		return layerString(r, anonymous, writeSpace)
	case reflect.Struct:
		var b bytes.Buffer
		typ := v.Type()
		if !anonymous {
			b.WriteByte('{')
		}
		for i := 0; i < v.NumField(); i++ {
			ftype := typ.Field(i)
			f := v.Field(i)
			if ftype.Anonymous {
				anonStr := layerString(f, true, writeSpace)
				writeSpace = writeSpace || anonStr != ""
				b.WriteString(anonStr)
			} else if ftype.PkgPath == "" {  
				if writeSpace {
					b.WriteByte(' ')
				}
				writeSpace = true
				fmt.Fprintf(&b, "%s=%s", typ.Field(i).Name, layerString(f, false, writeSpace))
			}
		}
		if !anonymous {
			b.WriteByte('}')
		}
		return b.String()
	case reflect.Slice:
		var b bytes.Buffer
		b.WriteByte('[')
		if v.Len() > 4 {
			fmt.Fprintf(&b, "..%d..", v.Len())
		} else {
			for j := 0; j < v.Len(); j++ {
				if j != 0 {
					b.WriteString(", ")
				}
				b.WriteString(layerString(v.Index(j), false, false))
			}
		}
		b.WriteByte(']')
		return b.String()
	}
	return fmt.Sprintf("%v", v.Interface())
}
const (
	longBytesLength = 128
)
func LongBytesGoString(buf []byte) string {
	if len(buf) < longBytesLength {
		return fmt.Sprintf("%#v", buf)
	}
	s := fmt.Sprintf("%#v", buf[:longBytesLength-1])
	s = strings.TrimSuffix(s, "}")
	return fmt.Sprintf("%s ... (%d bytes)}", s, len(buf))
}
func baseLayerString(value reflect.Value) string {
	t := value.Type()
	content := value.Field(0)
	c := make([]byte, content.Len())
	for i := range c {
		c[i] = byte(content.Index(i).Uint())
	}
	payload := value.Field(1)
	p := make([]byte, payload.Len())
	for i := range p {
		p[i] = byte(payload.Index(i).Uint())
	}
	return fmt.Sprintf("%s{Contents:%s, Payload:%s}", t.String(),
		LongBytesGoString(c),
		LongBytesGoString(p))
}
func layerGoString(i interface{}, b *bytes.Buffer) {
	if s, ok := i.(fmt.GoStringer); ok {
		b.WriteString(s.GoString())
		return
	}
	var v reflect.Value
	var ok bool
	if v, ok = i.(reflect.Value); !ok {
		v = reflect.ValueOf(i)
	}
	switch v.Kind() {
	case reflect.Ptr, reflect.Interface:
		if v.Kind() == reflect.Ptr {
			b.WriteByte('&')
		}
		layerGoString(v.Elem().Interface(), b)
	case reflect.Struct:
		t := v.Type()
		b.WriteString(t.String())
		b.WriteByte('{')
		for i := 0; i < v.NumField(); i++ {
			if i > 0 {
				b.WriteString(", ")
			}
			if t.Field(i).Name == "BaseLayer" {
				fmt.Fprintf(b, "BaseLayer:%s", baseLayerString(v.Field(i)))
			} else if v.Field(i).Kind() == reflect.Struct {
				fmt.Fprintf(b, "%s:", t.Field(i).Name)
				layerGoString(v.Field(i), b)
			} else if v.Field(i).Kind() == reflect.Ptr {
				b.WriteByte('&')
				layerGoString(v.Field(i), b)
			} else {
				fmt.Fprintf(b, "%s:%#v", t.Field(i).Name, v.Field(i))
			}
		}
		b.WriteByte('}')
	default:
		fmt.Fprintf(b, "%#v", i)
	}
}
func LayerGoString(l Layer) string {
	b := new(bytes.Buffer)
	layerGoString(l, b)
	return b.String()
}
func (p *packet) packetString() string {
	var b bytes.Buffer
	fmt.Fprintf(&b, "PACKET: %d bytes", len(p.Data()))
	if p.metadata.Truncated {
		b.WriteString(", truncated")
	}
	if p.metadata.Length > 0 {
		fmt.Fprintf(&b, ", wire length %d cap length %d", p.metadata.Length, p.metadata.CaptureLength)
	}
	if !p.metadata.Timestamp.IsZero() {
		fmt.Fprintf(&b, " @ %v", p.metadata.Timestamp)
	}
	b.WriteByte('\n')
	for i, l := range p.layers {
		fmt.Fprintf(&b, "- Layer %d (%02d bytes) = %s\n", i+1, len(l.LayerContents()), LayerString(l))
	}
	return b.String()
}
func (p *packet) packetDump() string {
	var b bytes.Buffer
	fmt.Fprintf(&b, "-- FULL PACKET DATA (%d bytes) ------------------------------------\n%s", len(p.data), hex.Dump(p.data))
	for i, l := range p.layers {
		fmt.Fprintf(&b, "--- Layer %d ---\n%s", i+1, LayerDump(l))
	}
	return b.String()
}
type eagerPacket struct {
	packet
}
var errNilDecoder = errors.New("NextDecoder passed nil decoder, probably an unsupported decode type")
func (p *eagerPacket) NextDecoder(next Decoder) error {
	if next == nil {
		return errNilDecoder
	}
	if p.last == nil {
		return errors.New("NextDecoder called, but no layers added yet")
	}
	d := p.last.LayerPayload()
	if len(d) == 0 {
		return nil
	}
	return next.Decode(d, p)
}
func (p *eagerPacket) initialDecode(dec Decoder) {
	defer p.recoverDecodeError()
	err := dec.Decode(p.data, p)
	if err != nil {
		p.addFinalDecodeError(err, nil)
	}
}
func (p *eagerPacket) LinkLayer() LinkLayer {
	return p.link
}
func (p *eagerPacket) NetworkLayer() NetworkLayer {
	return p.network
}
func (p *eagerPacket) TransportLayer() TransportLayer {
	return p.transport
}
func (p *eagerPacket) ApplicationLayer() ApplicationLayer {
	return p.application
}
func (p *eagerPacket) ErrorLayer() ErrorLayer {
	return p.failure
}
func (p *eagerPacket) Layers() []Layer {
	return p.layers
}
func (p *eagerPacket) Layer(t LayerType) Layer {
	for _, l := range p.layers {
		if l.LayerType() == t {
			return l
		}
	}
	return nil
}
func (p *eagerPacket) LayerClass(lc LayerClass) Layer {
	for _, l := range p.layers {
		if lc.Contains(l.LayerType()) {
			return l
		}
	}
	return nil
}
func (p *eagerPacket) String() string { return p.packetString() }
func (p *eagerPacket) Dump() string   { return p.packetDump() }
type lazyPacket struct {
	packet
	next Decoder
}
func (p *lazyPacket) NextDecoder(next Decoder) error {
	if next == nil {
		return errNilDecoder
	}
	p.next = next
	return nil
}
func (p *lazyPacket) decodeNextLayer() {
	if p.next == nil {
		return
	}
	d := p.data
	if p.last != nil {
		d = p.last.LayerPayload()
	}
	next := p.next
	p.next = nil
	if len(d) == 0 {
		return
	}
	defer p.recoverDecodeError()
	err := next.Decode(d, p)
	if err != nil {
		p.addFinalDecodeError(err, nil)
	}
}
func (p *lazyPacket) LinkLayer() LinkLayer {
	for p.link == nil && p.next != nil {
		p.decodeNextLayer()
	}
	return p.link
}
func (p *lazyPacket) NetworkLayer() NetworkLayer {
	for p.network == nil && p.next != nil {
		p.decodeNextLayer()
	}
	return p.network
}
func (p *lazyPacket) TransportLayer() TransportLayer {
	for p.transport == nil && p.next != nil {
		p.decodeNextLayer()
	}
	return p.transport
}
func (p *lazyPacket) ApplicationLayer() ApplicationLayer {
	for p.application == nil && p.next != nil {
		p.decodeNextLayer()
	}
	return p.application
}
func (p *lazyPacket) ErrorLayer() ErrorLayer {
	for p.failure == nil && p.next != nil {
		p.decodeNextLayer()
	}
	return p.failure
}
func (p *lazyPacket) Layers() []Layer {
	for p.next != nil {
		p.decodeNextLayer()
	}
	return p.layers
}
func (p *lazyPacket) Layer(t LayerType) Layer {
	for _, l := range p.layers {
		if l.LayerType() == t {
			return l
		}
	}
	numLayers := len(p.layers)
	for p.next != nil {
		p.decodeNextLayer()
		for _, l := range p.layers[numLayers:] {
			if l.LayerType() == t {
				return l
			}
		}
		numLayers = len(p.layers)
	}
	return nil
}
func (p *lazyPacket) LayerClass(lc LayerClass) Layer {
	for _, l := range p.layers {
		if lc.Contains(l.LayerType()) {
			return l
		}
	}
	numLayers := len(p.layers)
	for p.next != nil {
		p.decodeNextLayer()
		for _, l := range p.layers[numLayers:] {
			if lc.Contains(l.LayerType()) {
				return l
			}
		}
		numLayers = len(p.layers)
	}
	return nil
}
func (p *lazyPacket) String() string { p.Layers(); return p.packetString() }
func (p *lazyPacket) Dump() string   { p.Layers(); return p.packetDump() }
type DecodeOptions struct {
	Lazy bool
	NoCopy bool
	SkipDecodeRecovery bool
	DecodeStreamsAsDatagrams bool
}
var Default = DecodeOptions{}
var Lazy = DecodeOptions{Lazy: true}
var NoCopy = DecodeOptions{NoCopy: true}
var DecodeStreamsAsDatagrams = DecodeOptions{DecodeStreamsAsDatagrams: true}
func NewPacket(data []byte, firstLayerDecoder Decoder, options DecodeOptions) Packet {
	if !options.NoCopy {
		dataCopy := make([]byte, len(data))
		copy(dataCopy, data)
		data = dataCopy
	}
	if options.Lazy {
		p := &lazyPacket{
			packet: packet{data: data, decodeOptions: options},
			next:   firstLayerDecoder,
		}
		p.layers = p.initialLayers[:0]
		return p
	}
	p := &eagerPacket{
		packet: packet{data: data, decodeOptions: options},
	}
	p.layers = p.initialLayers[:0]
	p.initialDecode(firstLayerDecoder)
	return p
}
type PacketDataSource interface {
	ReadPacketData() (data []byte, ci CaptureInfo, err error)
}