-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
}