158 lines
6.0 KiB
Go
158 lines
6.0 KiB
Go
|
// 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")
|
||
|
}
|