// Copyright 2012 Google, Inc. All rights reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the LICENSE file in the root of the source // tree. package gopacket import ( "errors" ) // DecodeFeedback is used by DecodingLayer layers to provide decoding metadata. type DecodeFeedback interface { // SetTruncated should be called if during decoding you notice that a packet // is shorter than internal layer variables (HeaderLength, or the like) say it // should be. It sets packet.Metadata().Truncated. SetTruncated() } type nilDecodeFeedback struct{} func (nilDecodeFeedback) SetTruncated() {} // NilDecodeFeedback implements DecodeFeedback by doing nothing. var NilDecodeFeedback DecodeFeedback = nilDecodeFeedback{} // PacketBuilder is used by layer decoders to store the layers they've decoded, // and to defer future decoding via NextDecoder. // Typically, the pattern for use is: // func (m *myDecoder) Decode(data []byte, p PacketBuilder) error { // if myLayer, err := myDecodingLogic(data); err != nil { // return err // } else { // p.AddLayer(myLayer) // } // // maybe do this, if myLayer is a LinkLayer // p.SetLinkLayer(myLayer) // return p.NextDecoder(nextDecoder) // } type PacketBuilder interface { DecodeFeedback // AddLayer should be called by a decoder immediately upon successful // decoding of a layer. AddLayer(l Layer) // The following functions set the various specific layers in the final // packet. Note that if many layers call SetX, the first call is kept and all // other calls are ignored. SetLinkLayer(LinkLayer) SetNetworkLayer(NetworkLayer) SetTransportLayer(TransportLayer) SetApplicationLayer(ApplicationLayer) SetErrorLayer(ErrorLayer) // NextDecoder should be called by a decoder when they're done decoding a // packet layer but not done with decoding the entire packet. The next // decoder will be called to decode the last AddLayer's LayerPayload. // Because of this, NextDecoder must only be called once all other // PacketBuilder calls have been made. Set*Layer and AddLayer calls after // NextDecoder calls will behave incorrectly. NextDecoder(next Decoder) error // DumpPacketData is used solely for decoding. If you come across an error // you need to diagnose while processing a packet, call this and your packet's // data will be dumped to stderr so you can create a test. This should never // be called from a production decoder. DumpPacketData() // DecodeOptions returns the decode options DecodeOptions() *DecodeOptions } // Decoder is an interface for logic to decode a packet layer. Users may // implement a Decoder to handle their own strange packet types, or may use one // of the many decoders available in the 'layers' subpackage to decode things // for them. type Decoder interface { // Decode decodes the bytes of a packet, sending decoded values and other // information to PacketBuilder, and returning an error if unsuccessful. See // the PacketBuilder documentation for more details. Decode([]byte, PacketBuilder) error } // DecodeFunc wraps a function to make it a Decoder. type DecodeFunc func([]byte, PacketBuilder) error // Decode implements Decoder by calling itself. func (d DecodeFunc) Decode(data []byte, p PacketBuilder) error { // function, call thyself. return d(data, p) } // DecodePayload is a Decoder that returns a Payload layer containing all // remaining bytes. var DecodePayload Decoder = DecodeFunc(decodePayload) // DecodeUnknown is a Decoder that returns an Unknown layer containing all // remaining bytes, useful if you run up against a layer that you're unable to // decode yet. This layer is considered an ErrorLayer. var DecodeUnknown Decoder = DecodeFunc(decodeUnknown) // DecodeFragment is a Decoder that returns a Fragment layer containing all // remaining bytes. var DecodeFragment Decoder = DecodeFunc(decodeFragment) // LayerTypeZero is an invalid layer type, but can be used to determine whether // layer type has actually been set correctly. var LayerTypeZero = RegisterLayerType(0, LayerTypeMetadata{Name: "Unknown", Decoder: DecodeUnknown}) // LayerTypeDecodeFailure is the layer type for the default error layer. var LayerTypeDecodeFailure = RegisterLayerType(1, LayerTypeMetadata{Name: "DecodeFailure", Decoder: DecodeUnknown}) // LayerTypePayload is the layer type for a payload that we don't try to decode // but treat as a success, IE: an application-level payload. var LayerTypePayload = RegisterLayerType(2, LayerTypeMetadata{Name: "Payload", Decoder: DecodePayload}) // LayerTypeFragment is the layer type for a fragment of a layer transported // by an underlying layer that supports fragmentation. var LayerTypeFragment = RegisterLayerType(3, LayerTypeMetadata{Name: "Fragment", Decoder: DecodeFragment}) // DecodeFailure is a packet layer created if decoding of the packet data failed // for some reason. It implements ErrorLayer. LayerContents will be the entire // set of bytes that failed to parse, and Error will return the reason parsing // failed. type DecodeFailure struct { data []byte err error stack []byte } // Error returns the error encountered during decoding. func (d *DecodeFailure) Error() error { return d.err } // LayerContents implements Layer. func (d *DecodeFailure) LayerContents() []byte { return d.data } // LayerPayload implements Layer. func (d *DecodeFailure) LayerPayload() []byte { return nil } // String implements fmt.Stringer. func (d *DecodeFailure) String() string { return "Packet decoding error: " + d.Error().Error() } // Dump implements Dumper. func (d *DecodeFailure) Dump() (s string) { if d.stack != nil { s = string(d.stack) } return } // LayerType returns LayerTypeDecodeFailure func (d *DecodeFailure) LayerType() LayerType { return LayerTypeDecodeFailure } // decodeUnknown "decodes" unsupported data types by returning an error. // This decoder will thus always return a DecodeFailure layer. func decodeUnknown(data []byte, p PacketBuilder) error { return errors.New("Layer type not currently supported") }