From 063adcb7cd84dc560d54db5063dcc663b4faa6f5 Mon Sep 17 00:00:00 2001 From: Graeme Connell Date: Fri, 7 Dec 2012 16:19:16 -0700 Subject: [PATCH] Add EtherIP and IP4/6 encapsulation in IP packets. --- enums.go | 17 +++++++++++++---- layer_etherip.go | 26 ++++++++++++++++++++++++++ layer_sctp.go | 15 +++++++++++---- layertype.go | 3 +++ 4 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 layer_etherip.go diff --git a/enums.go b/enums.go index 1133227ae..ad9b7a9b6 100644 --- a/enums.go +++ b/enums.go @@ -42,10 +42,13 @@ func (e EthernetType) Decode(data []byte) (out DecodeResult, err error) { type IPProtocol uint8 const ( - IPProtocolICMP IPProtocol = 1 - IPProtocolTCP IPProtocol = 6 - IPProtocolUDP IPProtocol = 17 - IPProtocolSCTP IPProtocol = 132 + IPProtocolICMP IPProtocol = 1 + IPProtocolTCP IPProtocol = 6 + IPProtocolUDP IPProtocol = 17 + IPProtocolSCTP IPProtocol = 132 + IPProtocolIPv6 IPProtocol = 41 + IPProtocolIPIP IPProtocol = 94 + IPProtocolEtherIP IPProtocol = 97 ) func (ip IPProtocol) Decode(data []byte) (out DecodeResult, err error) { @@ -58,6 +61,12 @@ func (ip IPProtocol) Decode(data []byte) (out DecodeResult, err error) { return decodeICMP(data) case IPProtocolSCTP: return decodeSCTP(data) + case IPProtocolIPv6: + return decodeIPv6(data) + case IPProtocolIPIP: + return decodeIPv4(data) + case IPProtocolEtherIP: + return decodeEtherIP(data) } err = fmt.Errorf("Unsupported IP protocol %v", ip) return diff --git a/layer_etherip.go b/layer_etherip.go new file mode 100644 index 000000000..baf4034d5 --- /dev/null +++ b/layer_etherip.go @@ -0,0 +1,26 @@ +// Copyright (c) 2012 Google, Inc. All rights reserved. + +package gopacket + +import ( + "encoding/binary" + "errors" +) + +// EtherIP is the struct for storing RFC 3378 EtherIP packet headers. +type EtherIP struct { + Version uint8 + Reserved uint16 +} + +// LayerType returns LayerTypeEtherIP. +func (e *EtherIP) LayerType() LayerType { return LayerTypeEtherIP } + +func decodeEtherIP(data []byte) (out DecodeResult, _ error) { + out.DecodedLayer = &EtherIP{ + Version: data[0] >> 4, + Reserved: binary.BigEndian.Uint16(data[:2]) & 0x0fff, + } + out.NextDecoder = decodeEthernet + out.RemainingBytes = data[2:] +} diff --git a/layer_sctp.go b/layer_sctp.go index 9ac38844f..f500e354c 100644 --- a/layer_sctp.go +++ b/layer_sctp.go @@ -46,9 +46,14 @@ var decodeWithSCTPChunkTypePrefix decoderFunc = func(data []byte) (DecodeResult, // SCTPChunk contains the common fields in all SCTP chunks. type SCTPChunk struct { - Type SCTPChunkType - Flags uint8 - Length uint16 + Type SCTPChunkType + Flags uint8 + Length uint16 + // ActualLength is the total length of an SCTP chunk, including padding. + // SCTP chunks start and end on 4-byte boundaries. So if a chunk has a length + // of 18, it means that it has data up to and including byte 18, then padding + // up to the next 4-byte boundary, 20. In this case, Length would be 18, and + // ActualLength would be 20. ActualLength int } @@ -90,7 +95,7 @@ func decodeSCTPParameter(data []byte) SCTPParameter { // SCTPUnknownChunkType is the layer type returned when we don't recognize the // chunk type. Since there's a length in a known location, we can skip over // it even if we don't know what it is, and continue parsing the rest of the -// chunks. +// chunks. This chunk is stored as an ErrorLayer in the packet. type SCTPUnknownChunkType struct { SCTPChunk bytes []byte @@ -113,6 +118,7 @@ func (s *SCTPUnknownChunkType) LayerType() LayerType { return LayerTypeSCTPUnkno // and Flags. func (s *SCTPUnknownChunkType) Payload() []byte { return s.bytes } +// Error implements ErrorLayer. func (s *SCTPUnknownChunkType) Error() error { return fmt.Errorf("No decode method available for SCTP chunk type %s", s.Type) } @@ -156,6 +162,7 @@ func decodeSCTPData(data []byte) (out DecodeResult, _ error) { return } +// SCTPInitParameter is a parameter for an SCTP Init or InitAck packet. type SCTPInitParameter SCTPParameter // SCTPInit is used as the return value for both SCTPInit and SCTPInitAck diff --git a/layertype.go b/layertype.go index 67a8e294d..f5d27bc91 100644 --- a/layertype.go +++ b/layertype.go @@ -19,6 +19,7 @@ const ( LayerTypePayload LayerType = iota LayerTypeDecodeFailure LayerTypeEthernet + LayerTypeEtherIP LayerTypePPP LayerTypeIPv4 LayerTypeIPv6 @@ -60,6 +61,8 @@ func (l LayerType) String() string { return "DecodeFailure" case LayerTypeEthernet: return "Ethernet" + case LayerTypeEtherIP: + return "EtherIP" case LayerTypePPP: return "PPP" case LayerTypeIPv4: