Gopacket fails to properly decode SNAP layers
- Dominant language
- Go
- Stars
- 6.8k
- Forks
- 1.2k
- PR merge metrics
- No merged PRs in 30d
Description
Gopacket fails to decode SNAP layers when using a parser structured like the one in `parser.go` It tries to parse two LLC layers in a row and then tries to parse an unknown layer type, failing.
The reason that this happens is that the `CanDecode()` method of the SNAP struct in `llc.go` mistakenly returns `LayerTypeLLC`. It should be returning `LayerTypeSNAP`- almost all of the `CanDecode()` methods I've found return their own layer type (e.g. `LLC.CanDecode()` returns `LayerTypeLLC`, `Dot11MgmtProbeReq.CanDecode()` returns `LayerTypeDot11MgmtProbeReq`, etc.) As-is, gopacket treats the bytes following the LLC layer as a _second_ LLC layer. When the `LLC.NextLayerType()` (`llc.go` lines 61-69) function runs, it doesn't find a correct value:
```
func (l *LLC) NextLayerType() gopacket.LayerType {
switch {
case l.DSAP == 0xAA && l.SSAP == 0xAA:
return LayerTypeSNAP
case l.DSAP == 0x42 && l.SSAP == 0x42:
return LayerTypeSTP
}
return gopacket.LayerTypeZero // Not implemented
}
```
Since gopacket is now trying to treat a section of bytes as an LLC when they _aren't_ in fact an LLC, `l.DSAP` and `l.SSAP` refer to arbitrary bytes, which won't have one of those special values mentioned. `NextLayerType()` then returns `LayerTypeZero`, which errors as an unknown layer type, replicating the above symptoms.
The incorrect code, on lines 97-100 of `llc.go`:
```
// CanDecode returns the set of layer types that this DecodingLayer can decode.
func (s *SNAP) CanDecode() gopacket.LayerClass {
return LayerTypeLLC
}
```
What it should be:
```
// CanDecode returns the set of layer types that this DecodingLayer can decode.
func (s *SNAP) CanDecode() gopacket.LayerClass {
return LayerTypeSNAP
}
```
Contributor guide
Assessment
This issue has not been assessed yet.