func LayerString(l Layer) string {
	return fmt.Sprintf("%v\t%s", l.LayerType(), layerString(reflect.ValueOf(l), false, false))
}
LayerString outputs an individual layer as a string.  The layer is output
in a single line, with no trailing newline.  This function is specifically
designed to do the right thing for most layers... it follows the following
rules:
* If the Layer has a String function, just output that.
* Otherwise, output all exported fields in the layer, recursing into
exported slices and structs.
NOTE:  This is NOT THE SAME AS fmt's "%#v".  %#v will output both exported
and unexported fields... many times packet layers contain unexported stuff
that would just mess up the output of the layer, see for example the
Payload layer and it's internal 'data' field, which contains a large byte
array that would really mess up formatting.
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())
		}
	}
}