github.com/gopacket/gopacket@v1.1.0/parser.go (about) 1 // Copyright 2012 Google, Inc. All rights reserved. 2 // 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 5 // tree. 6 7 package gopacket 8 9 import ( 10 "fmt" 11 ) 12 13 // A container for single LayerType->DecodingLayer mapping. 14 type decodingLayerElem struct { 15 typ LayerType 16 dec DecodingLayer 17 } 18 19 // DecodingLayer is an interface for packet layers that can decode themselves. 20 // 21 // The important part of DecodingLayer is that they decode themselves in-place. 22 // Calling DecodeFromBytes on a DecodingLayer totally resets the entire layer to 23 // the new state defined by the data passed in. A returned error leaves the 24 // DecodingLayer in an unknown intermediate state, thus its fields should not be 25 // trusted. 26 // 27 // Because the DecodingLayer is resetting its own fields, a call to 28 // DecodeFromBytes should normally not require any memory allocation. 29 type DecodingLayer interface { 30 // DecodeFromBytes resets the internal state of this layer to the state 31 // defined by the passed-in bytes. Slices in the DecodingLayer may 32 // reference the passed-in data, so care should be taken to copy it 33 // first should later modification of data be required before the 34 // DecodingLayer is discarded. 35 DecodeFromBytes(data []byte, df DecodeFeedback) error 36 // CanDecode returns the set of LayerTypes this DecodingLayer can 37 // decode. For Layers that are also DecodingLayers, this will most 38 // often be that Layer's LayerType(). 39 CanDecode() LayerClass 40 // NextLayerType returns the LayerType which should be used to decode 41 // the LayerPayload. 42 NextLayerType() LayerType 43 // LayerPayload is the set of bytes remaining to decode after a call to 44 // DecodeFromBytes. 45 LayerPayload() []byte 46 } 47 48 // DecodingLayerFunc decodes given packet and stores decoded LayerType 49 // values into specified slice. Returns either first encountered 50 // unsupported LayerType value or decoding error. In case of success, 51 // returns (LayerTypeZero, nil). 52 type DecodingLayerFunc func([]byte, *[]LayerType) (LayerType, error) 53 54 // DecodingLayerContainer stores all DecodingLayer-s and serves as a 55 // searching tool for DecodingLayerParser. 56 type DecodingLayerContainer interface { 57 // Put adds new DecodingLayer to container. The new instance of 58 // the same DecodingLayerContainer is returned so it may be 59 // implemented as a value receiver. 60 Put(DecodingLayer) DecodingLayerContainer 61 // Decoder returns DecodingLayer to decode given LayerType and 62 // true if it was found. If no decoder found, return false. 63 Decoder(LayerType) (DecodingLayer, bool) 64 // LayersDecoder returns DecodingLayerFunc which decodes given 65 // packet, starting with specified LayerType and DecodeFeedback. 66 LayersDecoder(first LayerType, df DecodeFeedback) DecodingLayerFunc 67 } 68 69 // DecodingLayerSparse is a sparse array-based implementation of 70 // DecodingLayerContainer. Each DecodingLayer is addressed in an 71 // allocated slice by LayerType value itself. Though this is the 72 // fastest container it may be memory-consuming if used with big 73 // LayerType values. 74 type DecodingLayerSparse []DecodingLayer 75 76 // Put implements DecodingLayerContainer interface. 77 func (dl DecodingLayerSparse) Put(d DecodingLayer) DecodingLayerContainer { 78 maxLayerType := LayerType(len(dl) - 1) 79 for _, typ := range d.CanDecode().LayerTypes() { 80 if typ > maxLayerType { 81 maxLayerType = typ 82 } 83 } 84 85 if extra := maxLayerType - LayerType(len(dl)) + 1; extra > 0 { 86 dl = append(dl, make([]DecodingLayer, extra)...) 87 } 88 89 for _, typ := range d.CanDecode().LayerTypes() { 90 dl[typ] = d 91 } 92 return dl 93 } 94 95 // LayersDecoder implements DecodingLayerContainer interface. 96 func (dl DecodingLayerSparse) LayersDecoder(first LayerType, df DecodeFeedback) DecodingLayerFunc { 97 return LayersDecoder(dl, first, df) 98 } 99 100 // Decoder implements DecodingLayerContainer interface. 101 func (dl DecodingLayerSparse) Decoder(typ LayerType) (DecodingLayer, bool) { 102 if int64(typ) < int64(len(dl)) { 103 decoder := dl[typ] 104 return decoder, decoder != nil 105 } 106 return nil, false 107 } 108 109 // DecodingLayerArray is an array-based implementation of 110 // DecodingLayerContainer. Each DecodingLayer is searched linearly in 111 // an allocated slice in one-by-one fashion. 112 type DecodingLayerArray []decodingLayerElem 113 114 // Put implements DecodingLayerContainer interface. 115 func (dl DecodingLayerArray) Put(d DecodingLayer) DecodingLayerContainer { 116 TYPES: 117 for _, typ := range d.CanDecode().LayerTypes() { 118 for i := range dl { 119 if dl[i].typ == typ { 120 dl[i].dec = d 121 continue TYPES 122 } 123 } 124 dl = append(dl, decodingLayerElem{typ, d}) 125 } 126 return dl 127 } 128 129 // Decoder implements DecodingLayerContainer interface. 130 func (dl DecodingLayerArray) Decoder(typ LayerType) (DecodingLayer, bool) { 131 for i := range dl { 132 if dl[i].typ == typ { 133 return dl[i].dec, true 134 } 135 } 136 return nil, false 137 } 138 139 // LayersDecoder implements DecodingLayerContainer interface. 140 func (dl DecodingLayerArray) LayersDecoder(first LayerType, df DecodeFeedback) DecodingLayerFunc { 141 return LayersDecoder(dl, first, df) 142 } 143 144 // DecodingLayerMap is an map-based implementation of 145 // DecodingLayerContainer. Each DecodingLayer is searched in a map 146 // hashed by LayerType value. 147 type DecodingLayerMap map[LayerType]DecodingLayer 148 149 // Put implements DecodingLayerContainer interface. 150 func (dl DecodingLayerMap) Put(d DecodingLayer) DecodingLayerContainer { 151 for _, typ := range d.CanDecode().LayerTypes() { 152 if dl == nil { 153 dl = make(map[LayerType]DecodingLayer) 154 } 155 dl[typ] = d 156 } 157 return dl 158 } 159 160 // Decoder implements DecodingLayerContainer interface. 161 func (dl DecodingLayerMap) Decoder(typ LayerType) (DecodingLayer, bool) { 162 d, ok := dl[typ] 163 return d, ok 164 } 165 166 // LayersDecoder implements DecodingLayerContainer interface. 167 func (dl DecodingLayerMap) LayersDecoder(first LayerType, df DecodeFeedback) DecodingLayerFunc { 168 return LayersDecoder(dl, first, df) 169 } 170 171 // Static code check. 172 var ( 173 _ = []DecodingLayerContainer{ 174 DecodingLayerSparse(nil), 175 DecodingLayerMap(nil), 176 DecodingLayerArray(nil), 177 } 178 ) 179 180 // DecodingLayerParser parses a given set of layer types. See DecodeLayers for 181 // more information on how DecodingLayerParser should be used. 182 type DecodingLayerParser struct { 183 // DecodingLayerParserOptions is the set of options available to the 184 // user to define the parser's behavior. 185 DecodingLayerParserOptions 186 dlc DecodingLayerContainer 187 first LayerType 188 df DecodeFeedback 189 190 decodeFunc DecodingLayerFunc 191 192 // Truncated is set when a decode layer detects that the packet has been 193 // truncated. 194 Truncated bool 195 } 196 197 // AddDecodingLayer adds a decoding layer to the parser. This adds support for 198 // the decoding layer's CanDecode layers to the parser... should they be 199 // encountered, they'll be parsed. 200 func (l *DecodingLayerParser) AddDecodingLayer(d DecodingLayer) { 201 l.SetDecodingLayerContainer(l.dlc.Put(d)) 202 } 203 204 // SetTruncated is used by DecodingLayers to set the Truncated boolean in the 205 // DecodingLayerParser. Users should simply read Truncated after calling 206 // DecodeLayers. 207 func (l *DecodingLayerParser) SetTruncated() { 208 l.Truncated = true 209 } 210 211 // NewDecodingLayerParser creates a new DecodingLayerParser and adds in all 212 // of the given DecodingLayers with AddDecodingLayer. 213 // 214 // Each call to DecodeLayers will attempt to decode the given bytes first by 215 // treating them as a 'first'-type layer, then by using NextLayerType on 216 // subsequently decoded layers to find the next relevant decoder. Should a 217 // deoder not be available for the layer type returned by NextLayerType, 218 // decoding will stop. 219 // 220 // NewDecodingLayerParser uses DecodingLayerMap container by 221 // default. 222 func NewDecodingLayerParser(first LayerType, decoders ...DecodingLayer) *DecodingLayerParser { 223 dlp := &DecodingLayerParser{first: first} 224 dlp.df = dlp // Cast this once to the interface 225 // default container 226 dlc := DecodingLayerContainer(DecodingLayerMap(make(map[LayerType]DecodingLayer))) 227 for _, d := range decoders { 228 dlc = dlc.Put(d) 229 } 230 231 dlp.SetDecodingLayerContainer(dlc) 232 return dlp 233 } 234 235 // SetDecodingLayerContainer specifies container with decoders. This 236 // call replaces all decoders already registered in given instance of 237 // DecodingLayerParser. 238 func (l *DecodingLayerParser) SetDecodingLayerContainer(dlc DecodingLayerContainer) { 239 l.dlc = dlc 240 l.decodeFunc = l.dlc.LayersDecoder(l.first, l.df) 241 } 242 243 // DecodeLayers decodes as many layers as possible from the given data. It 244 // initially treats the data as layer type 'typ', then uses NextLayerType on 245 // each subsequent decoded layer until it gets to a layer type it doesn't know 246 // how to parse. 247 // 248 // For each layer successfully decoded, DecodeLayers appends the layer type to 249 // the decoded slice. DecodeLayers truncates the 'decoded' slice initially, so 250 // there's no need to empty it yourself. 251 // 252 // This decoding method is about an order of magnitude faster than packet 253 // decoding, because it only decodes known layers that have already been 254 // allocated. This means it doesn't need to allocate each layer it returns... 255 // instead it overwrites the layers that already exist. 256 // 257 // Example usage: 258 // 259 // func main() { 260 // var eth layers.Ethernet 261 // var ip4 layers.IPv4 262 // var ip6 layers.IPv6 263 // var tcp layers.TCP 264 // var udp layers.UDP 265 // var payload gopacket.Payload 266 // parser := gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, ð, &ip4, &ip6, &tcp, &udp, &payload) 267 // var source gopacket.PacketDataSource = getMyDataSource() 268 // decodedLayers := make([]gopacket.LayerType, 0, 10) 269 // for { 270 // data, _, err := source.ReadPacketData() 271 // if err != nil { 272 // fmt.Println("Error reading packet data: ", err) 273 // continue 274 // } 275 // fmt.Println("Decoding packet") 276 // err = parser.DecodeLayers(data, &decodedLayers) 277 // for _, typ := range decodedLayers { 278 // fmt.Println(" Successfully decoded layer type", typ) 279 // switch typ { 280 // case layers.LayerTypeEthernet: 281 // fmt.Println(" Eth ", eth.SrcMAC, eth.DstMAC) 282 // case layers.LayerTypeIPv4: 283 // fmt.Println(" IP4 ", ip4.SrcIP, ip4.DstIP) 284 // case layers.LayerTypeIPv6: 285 // fmt.Println(" IP6 ", ip6.SrcIP, ip6.DstIP) 286 // case layers.LayerTypeTCP: 287 // fmt.Println(" TCP ", tcp.SrcPort, tcp.DstPort) 288 // case layers.LayerTypeUDP: 289 // fmt.Println(" UDP ", udp.SrcPort, udp.DstPort) 290 // } 291 // } 292 // if decodedLayers.Truncated { 293 // fmt.Println(" Packet has been truncated") 294 // } 295 // if err != nil { 296 // fmt.Println(" Error encountered:", err) 297 // } 298 // } 299 // } 300 // 301 // If DecodeLayers is unable to decode the next layer type, it will return the 302 // error UnsupportedLayerType. 303 func (l *DecodingLayerParser) DecodeLayers(data []byte, decoded *[]LayerType) (err error) { 304 l.Truncated = false 305 if !l.IgnorePanic { 306 defer panicToError(&err) 307 } 308 typ, err := l.decodeFunc(data, decoded) 309 if typ != LayerTypeZero { 310 // no decoder 311 if l.IgnoreUnsupported { 312 return nil 313 } 314 return UnsupportedLayerType(typ) 315 } 316 return err 317 } 318 319 // UnsupportedLayerType is returned by DecodingLayerParser if DecodeLayers 320 // encounters a layer type that the DecodingLayerParser has no decoder for. 321 type UnsupportedLayerType LayerType 322 323 // Error implements the error interface, returning a string to say that the 324 // given layer type is unsupported. 325 func (e UnsupportedLayerType) Error() string { 326 return fmt.Sprintf("No decoder for layer type %v", LayerType(e)) 327 } 328 329 func panicToError(e *error) { 330 if r := recover(); r != nil { 331 *e = fmt.Errorf("panic: %v", r) 332 } 333 } 334 335 // DecodingLayerParserOptions provides options to affect the behavior of a given 336 // DecodingLayerParser. 337 type DecodingLayerParserOptions struct { 338 // IgnorePanic determines whether a DecodingLayerParser should stop 339 // panics on its own (by returning them as an error from DecodeLayers) 340 // or should allow them to raise up the stack. Handling errors does add 341 // latency to the process of decoding layers, but is much safer for 342 // callers. IgnorePanic defaults to false, thus if the caller does 343 // nothing decode panics will be returned as errors. 344 IgnorePanic bool 345 // IgnoreUnsupported will stop parsing and return a nil error when it 346 // encounters a layer it doesn't have a parser for, instead of returning an 347 // UnsupportedLayerType error. If this is true, it's up to the caller to make 348 // sure that all expected layers have been parsed (by checking the decoded 349 // slice). 350 IgnoreUnsupported bool 351 }