123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838 |
- package gopacket
- import (
- "bytes"
- "encoding/hex"
- "errors"
- "fmt"
- "io"
- "os"
- "reflect"
- "runtime/debug"
- "strings"
- "time"
- )
- type CaptureInfo struct {
-
- Timestamp time.Time
-
- CaptureLength int
-
-
- Length int
-
- InterfaceIndex int
- }
- 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)
- }
- func ConcatFinitePacketDataSources(pds ...PacketDataSource) PacketDataSource {
- c := concat(pds)
- return &c
- }
- type concat []PacketDataSource
- func (c *concat) ReadPacketData() (data []byte, ci CaptureInfo, err error) {
- for len(*c) > 0 {
- data, ci, err = (*c)[0].ReadPacketData()
- if err == io.EOF {
- *c = (*c)[1:]
- continue
- }
- return
- }
- return nil, CaptureInfo{}, io.EOF
- }
- type ZeroCopyPacketDataSource interface {
-
-
-
-
-
-
-
-
-
-
-
- ZeroCopyReadPacketData() (data []byte, ci CaptureInfo, err error)
- }
- type PacketSource struct {
- source PacketDataSource
- decoder Decoder
-
-
-
- DecodeOptions
- c chan Packet
- }
- func NewPacketSource(source PacketDataSource, decoder Decoder) *PacketSource {
- return &PacketSource{
- source: source,
- decoder: decoder,
- }
- }
- func (p *PacketSource) NextPacket() (Packet, error) {
- data, ci, err := p.source.ReadPacketData()
- if err != nil {
- return nil, err
- }
- packet := NewPacket(data, p.decoder, p.DecodeOptions)
- m := packet.Metadata()
- m.CaptureInfo = ci
- m.Truncated = m.Truncated || ci.CaptureLength < ci.Length
- return packet, nil
- }
- func (p *PacketSource) packetsToChannel() {
- defer close(p.c)
- for {
- packet, err := p.NextPacket()
- if err == io.EOF {
- return
- } else if err == nil {
- p.c <- packet
- }
- }
- }
- func (p *PacketSource) Packets() chan Packet {
- if p.c == nil {
- p.c = make(chan Packet, 1000)
- go p.packetsToChannel()
- }
- return p.c
- }
|