func decodeSCTPEmptyLayer(data []byte, p gopacket.PacketBuilder) error { sc := &SCTPEmptyLayer{ SCTPChunk: decodeSCTPChunk(data), } p.AddLayer(sc) return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix)) }
func decodeSCTPShutdown(data []byte, p gopacket.PacketBuilder) error { sc := &SCTPShutdown{ SCTPChunk: decodeSCTPChunk(data), CumulativeTSNAck: binary.BigEndian.Uint32(data[4:8]), } p.AddLayer(sc) return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix)) }
func decodeSCTPCookieEcho(data []byte, p gopacket.PacketBuilder) error { sc := &SCTPCookieEcho{ SCTPChunk: decodeSCTPChunk(data), } sc.Cookie = data[4:sc.Length] p.AddLayer(sc) return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix)) }
func decodeIPv6HopByHop(data []byte, p gopacket.PacketBuilder) error { i := &IPv6HopByHop{} err := i.DecodeFromBytes(data, p) p.AddLayer(i) if err != nil { return err } return p.NextDecoder(i.NextHeader) }
func decodeIPSecESP(data []byte, p gopacket.PacketBuilder) error { i := &IPSecESP{ BaseLayer: BaseLayer{data, nil}, SPI: binary.BigEndian.Uint32(data[:4]), Seq: binary.BigEndian.Uint32(data[4:8]), Encrypted: data[8:], } p.AddLayer(i) return nil }
func decodeEthernetCTP(data []byte, p gopacket.PacketBuilder) error { c := &EthernetCTP{ SkipCount: binary.LittleEndian.Uint16(data[:2]), BaseLayer: BaseLayer{data[:2], data[2:]}, } if c.SkipCount%2 != 0 { return fmt.Errorf("EthernetCTP skip count is odd: %d", c.SkipCount) } p.AddLayer(c) return p.NextDecoder(gopacket.DecodeFunc(decodeEthernetCTPFromFunctionType)) }
func decodeIPSecAH(data []byte, p gopacket.PacketBuilder) error { i := &IPSecAH{ ipv6ExtensionBase: decodeIPv6ExtensionBase(data), Reserved: binary.BigEndian.Uint16(data[2:4]), SPI: binary.BigEndian.Uint32(data[4:8]), Seq: binary.BigEndian.Uint32(data[8:12]), } i.AuthenticationData = i.Contents[12:] p.AddLayer(i) return p.NextDecoder(i.NextHeader) }
func decodeMPLS(data []byte, p gopacket.PacketBuilder) error { decoded := binary.BigEndian.Uint32(data[:4]) p.AddLayer(&MPLS{ Label: decoded >> 12, TrafficClass: uint8(decoded>>9) & 0x7, StackBottom: decoded&0x100 != 0, TTL: uint8(decoded), BaseLayer: BaseLayer{data[:4], data[4:]}, }) return p.NextDecoder(MPLSPayloadDecoder) }
func decodingLayerDecoder(d layerDecodingLayer, data []byte, p gopacket.PacketBuilder) error { err := d.DecodeFromBytes(data, p) if err != nil { return err } p.AddLayer(d) next := d.NextLayerType() if next == gopacket.LayerTypeZero { return nil } return p.NextDecoder(next) }
func decodeSNAP(data []byte, p gopacket.PacketBuilder) error { s := &SNAP{ OrganizationalCode: data[:3], Type: EthernetType(binary.BigEndian.Uint16(data[3:5])), BaseLayer: BaseLayer{data[:5], data[5:]}, } p.AddLayer(s) // BUG(gconnell): When decoding SNAP, we treat the SNAP type as an Ethernet // type. This may not actually be an ethernet type in all cases, // depending on the organizational code. Right now, we don't check. return p.NextDecoder(s.Type) }
// decodePPPoE decodes the PPPoE header (see http://tools.ietf.org/html/rfc2516). func decodePPPoE(data []byte, p gopacket.PacketBuilder) error { pppoe := &PPPoE{ Version: data[0] >> 4, Type: data[0] & 0x0F, Code: PPPoECode(data[1]), SessionId: binary.BigEndian.Uint16(data[2:4]), Length: binary.BigEndian.Uint16(data[4:6]), } pppoe.BaseLayer = BaseLayer{data[:6], data[6 : 6+pppoe.Length]} p.AddLayer(pppoe) return p.NextDecoder(pppoe.Code) }
func decodeIPv6Fragment(data []byte, p gopacket.PacketBuilder) error { i := &IPv6Fragment{ BaseLayer: BaseLayer{data[:8], data[8:]}, NextHeader: IPProtocol(data[0]), Reserved1: data[1], FragmentOffset: binary.BigEndian.Uint16(data[2:4]) >> 3, Reserved2: data[3] & 0x6 >> 1, MoreFragments: data[3]&0x1 != 0, Identification: binary.BigEndian.Uint32(data[4:8]), } p.AddLayer(i) return p.NextDecoder(gopacket.DecodeFragment) }
func decodeSCTPHeartbeat(data []byte, p gopacket.PacketBuilder) error { sc := &SCTPHeartbeat{ SCTPChunk: decodeSCTPChunk(data), } paramData := data[4:sc.Length] for len(paramData) > 0 { p := SCTPHeartbeatParameter(decodeSCTPParameter(paramData)) paramData = paramData[p.ActualLength:] sc.Parameters = append(sc.Parameters, p) } p.AddLayer(sc) return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix)) }
func decodeIPv6Destination(data []byte, p gopacket.PacketBuilder) error { i := &IPv6Destination{ ipv6ExtensionBase: decodeIPv6ExtensionBase(data), // We guess we'll 1-2 options, one regular option at least, then maybe one // padding option. Options: make([]IPv6DestinationOption, 0, 2), } var opt *IPv6DestinationOption for d := i.Contents[2:]; len(d) > 0; d = d[opt.ActualLength:] { i.Options = append(i.Options, IPv6DestinationOption(decodeIPv6HeaderTLVOption(d))) opt = &i.Options[len(i.Options)-1] } p.AddLayer(i) return p.NextDecoder(i.NextHeader) }
func decodeSCTPInit(data []byte, p gopacket.PacketBuilder) error { sc := &SCTPInit{ SCTPChunk: decodeSCTPChunk(data), InitiateTag: binary.BigEndian.Uint32(data[4:8]), AdvertisedReceiverWindowCredit: binary.BigEndian.Uint32(data[8:12]), OutboundStreams: binary.BigEndian.Uint16(data[12:14]), InboundStreams: binary.BigEndian.Uint16(data[14:16]), InitialTSN: binary.BigEndian.Uint32(data[16:20]), } paramData := data[20:sc.ActualLength] for len(paramData) > 0 { p := SCTPInitParameter(decodeSCTPParameter(paramData)) paramData = paramData[p.ActualLength:] sc.Parameters = append(sc.Parameters, p) } p.AddLayer(sc) return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix)) }
func decodeIPv6(data []byte, p gopacket.PacketBuilder) error { ip6 := &IPv6{} err := ip6.DecodeFromBytes(data, p) p.AddLayer(ip6) p.SetNetworkLayer(ip6) if ip6.HopByHop != nil { // TODO(gconnell): Since HopByHop is now an integral part of the IPv6 // layer, should it actually be added as its own layer? I'm leaning towards // no. p.AddLayer(ip6.HopByHop) } if err != nil { return err } if ip6.HopByHop != nil { return p.NextDecoder(ip6.HopByHop.NextHeader) } return p.NextDecoder(ip6.NextHeader) }
func decodeCiscoDiscovery(data []byte, p gopacket.PacketBuilder) error { c := &CiscoDiscovery{ Version: data[0], TTL: data[1], Checksum: binary.BigEndian.Uint16(data[2:4]), } if c.Version != 1 && c.Version != 2 { return fmt.Errorf("Invalid CiscoDiscovery version number %d", c.Version) } var err error c.Values, err = decodeCiscoDiscoveryTLVs(data[4:]) if err != nil { return err } c.Contents = data[0:4] c.Payload = data[4:] p.AddLayer(c) return p.NextDecoder(gopacket.DecodeFunc(decodeCiscoDiscoveryInfo)) }
func decodeIPv6Routing(data []byte, p gopacket.PacketBuilder) error { i := &IPv6Routing{ ipv6ExtensionBase: decodeIPv6ExtensionBase(data), RoutingType: data[2], SegmentsLeft: data[3], Reserved: data[4:8], } switch i.RoutingType { case 0: // Source routing if (len(data)-8)%16 != 0 { return fmt.Errorf("Invalid IPv6 source routing, length of type 0 packet %d", len(data)) } for d := i.Contents[8:]; len(d) >= 16; d = d[16:] { i.SourceRoutingIPs = append(i.SourceRoutingIPs, net.IP(d[:16])) } } p.AddLayer(i) return p.NextDecoder(i.NextHeader) }
func decodeLoopback(data []byte, p gopacket.PacketBuilder) error { // The protocol could be either big-endian or little-endian, we're // not sure. But we're PRETTY sure that the value is less than // 256, so we can check the first two bytes. var prot uint32 if data[0] == 0 && data[1] == 0 { prot = binary.BigEndian.Uint32(data[:4]) } else { prot = binary.LittleEndian.Uint32(data[:4]) } if prot > 0xFF { return fmt.Errorf("Invalid loopback protocol %q", data[:4]) } l := &Loopback{ BaseLayer: BaseLayer{data[:4], data[4:]}, Family: ProtocolFamily(prot), } p.AddLayer(l) return p.NextDecoder(l.Family) }
func decodeSCTPChunkTypeUnknown(data []byte, p gopacket.PacketBuilder) error { sc := &SCTPUnknownChunkType{SCTPChunk: decodeSCTPChunk(data)} sc.bytes = data[:sc.ActualLength] p.AddLayer(sc) p.SetErrorLayer(sc) return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix)) }
func decodeLinuxSLL(data []byte, p gopacket.PacketBuilder) error { sll := &LinuxSLL{} if err := sll.DecodeFromBytes(data, p); err != nil { return err } p.AddLayer(sll) p.SetLinkLayer(sll) return p.NextDecoder(sll.EthernetType) }
func decodeSCTPSack(data []byte, p gopacket.PacketBuilder) error { sc := &SCTPSack{ SCTPChunk: decodeSCTPChunk(data), CumulativeTSNAck: binary.BigEndian.Uint32(data[4:8]), AdvertisedReceiverWindowCredit: binary.BigEndian.Uint32(data[8:12]), NumGapACKs: binary.BigEndian.Uint16(data[12:14]), NumDuplicateTSNs: binary.BigEndian.Uint16(data[14:16]), } // We maximize gapAcks and dupTSNs here so we're not allocating tons // of memory based on a user-controlable field. Our maximums are not exact, // but should give us sane defaults... we'll still hit slice boundaries and // fail if the user-supplied values are too high (in the for loops below), but // the amount of memory we'll have allocated because of that should be small // (< sc.ActualLength) gapAcks := sc.SCTPChunk.ActualLength / 2 dupTSNs := (sc.SCTPChunk.ActualLength - gapAcks*2) / 4 if gapAcks > int(sc.NumGapACKs) { gapAcks = int(sc.NumGapACKs) } if dupTSNs > int(sc.NumDuplicateTSNs) { dupTSNs = int(sc.NumDuplicateTSNs) } sc.GapACKs = make([]uint16, 0, gapAcks) sc.DuplicateTSNs = make([]uint32, 0, dupTSNs) bytesRemaining := data[16:] for i := 0; i < int(sc.NumGapACKs); i++ { sc.GapACKs = append(sc.GapACKs, binary.BigEndian.Uint16(bytesRemaining[:2])) bytesRemaining = bytesRemaining[2:] } for i := 0; i < int(sc.NumDuplicateTSNs); i++ { sc.DuplicateTSNs = append(sc.DuplicateTSNs, binary.BigEndian.Uint32(bytesRemaining[:4])) bytesRemaining = bytesRemaining[4:] } p.AddLayer(sc) return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix)) }
func decodeUDP(data []byte, p gopacket.PacketBuilder) error { udp := &UDP{} err := udp.DecodeFromBytes(data, p) p.AddLayer(udp) p.SetTransportLayer(udp) if err != nil { return err } return p.NextDecoder(gopacket.LayerTypePayload) }
func decodeIPv4(data []byte, p gopacket.PacketBuilder) error { ip := &IPv4{} err := ip.DecodeFromBytes(data, p) p.AddLayer(ip) p.SetNetworkLayer(ip) if err != nil { return err } return p.NextDecoder(ip.NextLayerType()) }
func decodeEthernet(data []byte, p gopacket.PacketBuilder) error { eth := &Ethernet{} err := eth.DecodeFromBytes(data, p) if err != nil { return err } p.AddLayer(eth) p.SetLinkLayer(eth) return p.NextDecoder(eth.EthernetType) }
func decodeFDDI(data []byte, p gopacket.PacketBuilder) error { f := &FDDI{ FrameControl: FDDIFrameControl(data[0] & 0xF8), Priority: data[0] & 0x07, SrcMAC: net.HardwareAddr(data[1:7]), DstMAC: net.HardwareAddr(data[7:13]), BaseLayer: BaseLayer{data[:13], data[13:]}, } p.SetLinkLayer(f) p.AddLayer(f) return p.NextDecoder(f.FrameControl) }
func decodeSCTP(data []byte, p gopacket.PacketBuilder) error { sctp := &SCTP{ SrcPort: SCTPPort(binary.BigEndian.Uint16(data[:2])), sPort: data[:2], DstPort: SCTPPort(binary.BigEndian.Uint16(data[2:4])), dPort: data[2:4], VerificationTag: binary.BigEndian.Uint32(data[4:8]), Checksum: binary.BigEndian.Uint32(data[8:12]), BaseLayer: BaseLayer{data[:12], data[12:]}, } p.AddLayer(sctp) p.SetTransportLayer(sctp) return p.NextDecoder(sctpChunkTypePrefixDecoder) }
func decodeRUDP(data []byte, p gopacket.PacketBuilder) error { r := &RUDP{ SYN: data[0]&0x80 != 0, ACK: data[0]&0x40 != 0, EACK: data[0]&0x20 != 0, RST: data[0]&0x10 != 0, NUL: data[0]&0x08 != 0, Version: data[0] & 0x3, HeaderLength: data[1], SrcPort: RUDPPort(data[2]), DstPort: RUDPPort(data[3]), DataLength: binary.BigEndian.Uint16(data[4:6]), Seq: binary.BigEndian.Uint32(data[6:10]), Ack: binary.BigEndian.Uint32(data[10:14]), Checksum: binary.BigEndian.Uint32(data[14:18]), } if r.HeaderLength < 9 { return fmt.Errorf("RUDP packet with too-short header length %d", r.HeaderLength) } hlen := int(r.HeaderLength) * 2 r.Contents = data[:hlen] r.Payload = data[hlen : hlen+int(r.DataLength)] r.VariableHeaderArea = data[18:hlen] headerData := r.VariableHeaderArea switch { case r.SYN: if len(headerData) != 6 { return fmt.Errorf("RUDP packet invalid SYN header length: %d", len(headerData)) } r.RUDPHeaderSYN = &RUDPHeaderSYN{ MaxOutstandingSegments: binary.BigEndian.Uint16(headerData[:2]), MaxSegmentSize: binary.BigEndian.Uint16(headerData[2:4]), OptionFlags: binary.BigEndian.Uint16(headerData[4:6]), } case r.EACK: if len(headerData)%4 != 0 { return fmt.Errorf("RUDP packet invalid EACK header length: %d", len(headerData)) } r.RUDPHeaderEACK = &RUDPHeaderEACK{make([]uint32, len(headerData)/4)} for i := 0; i < len(headerData); i += 4 { r.SeqsReceivedOK[i/4] = binary.BigEndian.Uint32(headerData[i : i+4]) } } p.AddLayer(r) p.SetTransportLayer(r) return p.NextDecoder(gopacket.LayerTypePayload) }
func decodeSCTPData(data []byte, p gopacket.PacketBuilder) error { sc := &SCTPData{ SCTPChunk: decodeSCTPChunk(data), Unordered: data[1]&0x4 != 0, BeginFragment: data[1]&0x2 != 0, EndFragment: data[1]&0x1 != 0, TSN: binary.BigEndian.Uint32(data[4:8]), StreamId: binary.BigEndian.Uint16(data[8:10]), StreamSequence: binary.BigEndian.Uint16(data[10:12]), PayloadProtocol: binary.BigEndian.Uint32(data[12:16]), } // Length is the length in bytes of the data, INCLUDING the 16-byte header. sc.PayloadData = data[16:sc.Length] p.AddLayer(sc) p.SetApplicationLayer(sc) return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix)) }
// decodeEthernetCTPFromFunctionType reads in the first 2 bytes to determine the EthernetCTP // layer type to decode next, then decodes based on that. func decodeEthernetCTPFromFunctionType(data []byte, p gopacket.PacketBuilder) error { function := EthernetCTPFunction(binary.LittleEndian.Uint16(data[:2])) switch function { case EthernetCTPFunctionReply: reply := &EthernetCTPReply{ Function: function, ReceiptNumber: binary.LittleEndian.Uint16(data[2:4]), Data: data[4:], BaseLayer: BaseLayer{data, nil}, } p.AddLayer(reply) p.SetApplicationLayer(reply) return nil case EthernetCTPFunctionForwardData: forward := &EthernetCTPForwardData{ Function: function, ForwardAddress: data[2:8], BaseLayer: BaseLayer{data[:8], data[8:]}, } p.AddLayer(forward) return p.NextDecoder(gopacket.DecodeFunc(decodeEthernetCTPFromFunctionType)) } return fmt.Errorf("Unknown EthernetCTP function type %v", function) }