1 // Copyright 2012 Google, Inc. All rights reserved.
3 // Use of this source code is governed by a BSD-style license
4 // that can be found in the LICENSE file in the root of the source
13 // DecodingLayer is an interface for packet layers that can decode themselves.
15 // The important part of DecodingLayer is that they decode themselves in-place.
16 // Calling DecodeFromBytes on a DecodingLayer totally resets the entire layer to
17 // the new state defined by the data passed in. A returned error leaves the
18 // DecodingLayer in an unknown intermediate state, thus its fields should not be
21 // Because the DecodingLayer is resetting its own fields, a call to
22 // DecodeFromBytes should normally not require any memory allocation.
23 type DecodingLayer interface {
24 // DecodeFromBytes resets the internal state of this layer to the state
25 // defined by the passed-in bytes. Slices in the DecodingLayer may
26 // reference the passed-in data, so care should be taken to copy it
27 // first should later modification of data be required before the
28 // DecodingLayer is discarded.
29 DecodeFromBytes(data []byte, df DecodeFeedback) error
30 // CanDecode returns the set of LayerTypes this DecodingLayer can
31 // decode. For Layers that are also DecodingLayers, this will most
32 // often be that Layer's LayerType().
33 CanDecode() LayerClass
34 // NextLayerType returns the LayerType which should be used to decode
36 NextLayerType() LayerType
37 // LayerPayload is the set of bytes remaining to decode after a call to
42 // DecodingLayerParser parses a given set of layer types. See DecodeLayers for
43 // more information on how DecodingLayerParser should be used.
44 type DecodingLayerParser struct {
45 // DecodingLayerParserOptions is the set of options available to the
46 // user to define the parser's behavior.
47 DecodingLayerParserOptions
49 decoders map[LayerType]DecodingLayer
51 // Truncated is set when a decode layer detects that the packet has been
56 // AddDecodingLayer adds a decoding layer to the parser. This adds support for
57 // the decoding layer's CanDecode layers to the parser... should they be
58 // encountered, they'll be parsed.
59 func (l *DecodingLayerParser) AddDecodingLayer(d DecodingLayer) {
60 for _, typ := range d.CanDecode().LayerTypes() {
65 // SetTruncated is used by DecodingLayers to set the Truncated boolean in the
66 // DecodingLayerParser. Users should simply read Truncated after calling
68 func (l *DecodingLayerParser) SetTruncated() {
72 // NewDecodingLayerParser creates a new DecodingLayerParser and adds in all
73 // of the given DecodingLayers with AddDecodingLayer.
75 // Each call to DecodeLayers will attempt to decode the given bytes first by
76 // treating them as a 'first'-type layer, then by using NextLayerType on
77 // subsequently decoded layers to find the next relevant decoder. Should a
78 // deoder not be available for the layer type returned by NextLayerType,
79 // decoding will stop.
80 func NewDecodingLayerParser(first LayerType, decoders ...DecodingLayer) *DecodingLayerParser {
81 dlp := &DecodingLayerParser{
82 decoders: make(map[LayerType]DecodingLayer),
85 dlp.df = dlp // Cast this once to the interface
86 for _, d := range decoders {
87 dlp.AddDecodingLayer(d)
92 // DecodeLayers decodes as many layers as possible from the given data. It
93 // initially treats the data as layer type 'typ', then uses NextLayerType on
94 // each subsequent decoded layer until it gets to a layer type it doesn't know
97 // For each layer successfully decoded, DecodeLayers appends the layer type to
98 // the decoded slice. DecodeLayers truncates the 'decoded' slice initially, so
99 // there's no need to empty it yourself.
101 // This decoding method is about an order of magnitude faster than packet
102 // decoding, because it only decodes known layers that have already been
103 // allocated. This means it doesn't need to allocate each layer it returns...
104 // instead it overwrites the layers that already exist.
108 // var eth layers.Ethernet
109 // var ip4 layers.IPv4
110 // var ip6 layers.IPv6
111 // var tcp layers.TCP
112 // var udp layers.UDP
113 // var payload gopacket.Payload
114 // parser := gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, ð, &ip4, &ip6, &tcp, &udp, &payload)
115 // var source gopacket.PacketDataSource = getMyDataSource()
116 // decodedLayers := make([]gopacket.LayerType, 0, 10)
118 // data, _, err := source.ReadPacketData()
120 // fmt.Println("Error reading packet data: ", err)
123 // fmt.Println("Decoding packet")
124 // err = parser.DecodeLayers(data, &decodedLayers)
125 // for _, typ := range decodedLayers {
126 // fmt.Println(" Successfully decoded layer type", typ)
128 // case layers.LayerTypeEthernet:
129 // fmt.Println(" Eth ", eth.SrcMAC, eth.DstMAC)
130 // case layers.LayerTypeIPv4:
131 // fmt.Println(" IP4 ", ip4.SrcIP, ip4.DstIP)
132 // case layers.LayerTypeIPv6:
133 // fmt.Println(" IP6 ", ip6.SrcIP, ip6.DstIP)
134 // case layers.LayerTypeTCP:
135 // fmt.Println(" TCP ", tcp.SrcPort, tcp.DstPort)
136 // case layers.LayerTypeUDP:
137 // fmt.Println(" UDP ", udp.SrcPort, udp.DstPort)
140 // if decodedLayers.Truncated {
141 // fmt.Println(" Packet has been truncated")
144 // fmt.Println(" Error encountered:", err)
149 // If DecodeLayers is unable to decode the next layer type, it will return the
150 // error UnsupportedLayerType.
151 func (l *DecodingLayerParser) DecodeLayers(data []byte, decoded *[]LayerType) (err error) {
154 defer panicToError(&err)
157 *decoded = (*decoded)[:0] // Truncated decoded layers.
159 decoder, ok := l.decoders[typ]
161 return UnsupportedLayerType(typ)
162 } else if err = decoder.DecodeFromBytes(data, l.df); err != nil {
165 *decoded = append(*decoded, typ)
166 typ = decoder.NextLayerType()
167 data = decoder.LayerPayload()
172 // UnsupportedLayerType is returned by DecodingLayerParser if DecodeLayers
173 // encounters a layer type that the DecodingLayerParser has no decoder for.
174 type UnsupportedLayerType LayerType
176 // Error implements the error interface, returning a string to say that the
177 // given layer type is unsupported.
178 func (e UnsupportedLayerType) Error() string {
179 return fmt.Sprintf("No decoder for layer type %v", LayerType(e))
182 func panicToError(e *error) {
183 if r := recover(); r != nil {
184 *e = fmt.Errorf("panic: %v", r)
188 // DecodingLayerParserOptions provides options to affect the behavior of a given
189 // DecodingLayerParser.
190 type DecodingLayerParserOptions struct {
191 // IgnorePanic determines whether a DecodingLayerParser should stop
192 // panics on its own (by returning them as an error from DecodeLayers)
193 // or should allow them to raise up the stack. Handling errors does add
194 // latency to the process of decoding layers, but is much safer for
195 // callers. IgnorePanic defaults to false, thus if the caller does
196 // nothing decode panics will be returned as errors.