diff options
Diffstat (limited to 'vendor/github.com/google/gopacket/layers')
83 files changed, 36430 insertions, 0 deletions
diff --git a/vendor/github.com/google/gopacket/layers/.linted b/vendor/github.com/google/gopacket/layers/.linted new file mode 100644 index 0000000..afe7689 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/.linted @@ -0,0 +1,41 @@ +arp.go +base.go +base_test.go +bfd.go +cdp.go +ctp.go +decode_test.go +dhcp_test.go +dhcpv4.go +dns.go +dns_test.go +doc.go +dot11_test.go +dot1q.go +dot1q_test.go +eapol.go +etherip.go +fddi.go +gen.go +gre.go +gre_test.go +iana_ports.go +icmp6_test.go +igmp_test.go +ip4_test.go +ipsec.go +ipsec_test.go +loopback.go +mpls_test.go +ntp_test.go +ports.go +ppp.go +prism_test.go +radiotap_test.go +sflow_test.go +tcp_test.go +udp_test.go +usb_test.go +vrrp_test.go +vxlan.go +vxlan_test.go diff --git a/vendor/github.com/google/gopacket/layers/arp.go b/vendor/github.com/google/gopacket/layers/arp.go new file mode 100644 index 0000000..49e05ac --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/arp.go @@ -0,0 +1,109 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// Copyright 2009-2011 Andreas Krennmair. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "errors" + + "github.com/google/gopacket" +) + +// Potential values for ARP.Operation. +const ( + ARPRequest = 1 + ARPReply = 2 +) + +// ARP is a ARP packet header. +type ARP struct { + BaseLayer + AddrType LinkType + Protocol EthernetType + HwAddressSize uint8 + ProtAddressSize uint8 + Operation uint16 + SourceHwAddress []byte + SourceProtAddress []byte + DstHwAddress []byte + DstProtAddress []byte +} + +// LayerType returns LayerTypeARP +func (arp *ARP) LayerType() gopacket.LayerType { return LayerTypeARP } + +// DecodeFromBytes decodes the given bytes into this layer. +func (arp *ARP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + arp.AddrType = LinkType(binary.BigEndian.Uint16(data[0:2])) + arp.Protocol = EthernetType(binary.BigEndian.Uint16(data[2:4])) + arp.HwAddressSize = data[4] + arp.ProtAddressSize = data[5] + arp.Operation = binary.BigEndian.Uint16(data[6:8]) + arp.SourceHwAddress = data[8 : 8+arp.HwAddressSize] + arp.SourceProtAddress = data[8+arp.HwAddressSize : 8+arp.HwAddressSize+arp.ProtAddressSize] + arp.DstHwAddress = data[8+arp.HwAddressSize+arp.ProtAddressSize : 8+2*arp.HwAddressSize+arp.ProtAddressSize] + arp.DstProtAddress = data[8+2*arp.HwAddressSize+arp.ProtAddressSize : 8+2*arp.HwAddressSize+2*arp.ProtAddressSize] + + arpLength := 8 + 2*arp.HwAddressSize + 2*arp.ProtAddressSize + arp.Contents = data[:arpLength] + arp.Payload = data[arpLength:] + return nil +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (arp *ARP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + size := 8 + len(arp.SourceHwAddress) + len(arp.SourceProtAddress) + len(arp.DstHwAddress) + len(arp.DstProtAddress) + bytes, err := b.PrependBytes(size) + if err != nil { + return err + } + if opts.FixLengths { + if len(arp.SourceHwAddress) != len(arp.DstHwAddress) { + return errors.New("mismatched hardware address sizes") + } + arp.HwAddressSize = uint8(len(arp.SourceHwAddress)) + if len(arp.SourceProtAddress) != len(arp.DstProtAddress) { + return errors.New("mismatched prot address sizes") + } + arp.ProtAddressSize = uint8(len(arp.SourceProtAddress)) + } + binary.BigEndian.PutUint16(bytes, uint16(arp.AddrType)) + binary.BigEndian.PutUint16(bytes[2:], uint16(arp.Protocol)) + bytes[4] = arp.HwAddressSize + bytes[5] = arp.ProtAddressSize + binary.BigEndian.PutUint16(bytes[6:], arp.Operation) + start := 8 + for _, addr := range [][]byte{ + arp.SourceHwAddress, + arp.SourceProtAddress, + arp.DstHwAddress, + arp.DstProtAddress, + } { + copy(bytes[start:], addr) + start += len(addr) + } + return nil +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (arp *ARP) CanDecode() gopacket.LayerClass { + return LayerTypeARP +} + +// NextLayerType returns the layer type contained by this DecodingLayer. +func (arp *ARP) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypePayload +} + +func decodeARP(data []byte, p gopacket.PacketBuilder) error { + + arp := &ARP{} + return decodingLayerDecoder(arp, data, p) +} diff --git a/vendor/github.com/google/gopacket/layers/base.go b/vendor/github.com/google/gopacket/layers/base.go new file mode 100644 index 0000000..cd59b46 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/base.go @@ -0,0 +1,52 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "github.com/google/gopacket" +) + +// BaseLayer is a convenience struct which implements the LayerData and +// LayerPayload functions of the Layer interface. +type BaseLayer struct { + // Contents is the set of bytes that make up this layer. IE: for an + // Ethernet packet, this would be the set of bytes making up the + // Ethernet frame. + Contents []byte + // Payload is the set of bytes contained by (but not part of) this + // Layer. Again, to take Ethernet as an example, this would be the + // set of bytes encapsulated by the Ethernet protocol. + Payload []byte +} + +// LayerContents returns the bytes of the packet layer. +func (b *BaseLayer) LayerContents() []byte { return b.Contents } + +// LayerPayload returns the bytes contained within the packet layer. +func (b *BaseLayer) LayerPayload() []byte { return b.Payload } + +type layerDecodingLayer interface { + gopacket.Layer + DecodeFromBytes([]byte, gopacket.DecodeFeedback) error + NextLayerType() gopacket.LayerType +} + +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) +} + +// hacky way to zero out memory... there must be a better way? +var lotsOfZeros [1024]byte diff --git a/vendor/github.com/google/gopacket/layers/base_test.go b/vendor/github.com/google/gopacket/layers/base_test.go new file mode 100644 index 0000000..4be7480 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/base_test.go @@ -0,0 +1,42 @@ +// Copyright 2012, Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +// This file contains some test helper functions. + +package layers + +import ( + "github.com/google/gopacket" + "testing" +) + +func min(a, b int) int { + if a < b { + return a + } + return b +} + +func checkLayers(p gopacket.Packet, want []gopacket.LayerType, t *testing.T) { + layers := p.Layers() + t.Log("Checking packet layers, want", want) + for _, l := range layers { + t.Logf(" Got layer %v, %d bytes, payload of %d bytes", l.LayerType(), + len(l.LayerContents()), len(l.LayerPayload())) + } + t.Log(p) + if len(layers) != len(want) { + t.Errorf(" Number of layers mismatch: got %d want %d", len(layers), + len(want)) + return + } + for i, l := range layers { + if l.LayerType() != want[i] { + t.Errorf(" Layer %d mismatch: got %v want %v", i, l.LayerType(), + want[i]) + } + } +} diff --git a/vendor/github.com/google/gopacket/layers/bfd.go b/vendor/github.com/google/gopacket/layers/bfd.go new file mode 100644 index 0000000..43030fb --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/bfd.go @@ -0,0 +1,481 @@ +// Copyright 2017 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. +// + +package layers + +import ( + "encoding/binary" + "errors" + + "github.com/google/gopacket" +) + +// BFD Control Packet Format +// ------------------------- +// The current version of BFD's RFC (RFC 5880) contains the following +// diagram for the BFD Control packet format: +// +// 0 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// |Vers | Diag |Sta|P|F|C|A|D|M| Detect Mult | Length | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | My Discriminator | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Your Discriminator | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Desired Min TX Interval | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Required Min RX Interval | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Required Min Echo RX Interval | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// An optional Authentication Section MAY be present: +// +// 0 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Auth Type | Auth Len | Authentication Data... | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// +// Simple Password Authentication Section Format +// --------------------------------------------- +// 0 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Auth Type | Auth Len | Auth Key ID | Password... | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | ... | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// +// Keyed MD5 and Meticulous Keyed MD5 Authentication Section Format +// ---------------------------------------------------------------- +// 0 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Auth Type | Auth Len | Auth Key ID | Reserved | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Sequence Number | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Auth Key/Digest... | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | ... | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// +// Keyed SHA1 and Meticulous Keyed SHA1 Authentication Section Format +// ------------------------------------------------------------------ +// 0 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Auth Type | Auth Len | Auth Key ID | Reserved | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Sequence Number | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Auth Key/Hash... | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | ... | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// From https://tools.ietf.org/rfc/rfc5880.txt +const bfdMinimumRecordSizeInBytes int = 24 + +// BFDVersion represents the version as decoded from the BFD control message +type BFDVersion uint8 + +// BFDDiagnostic represents diagnostic infomation about a BFD session +type BFDDiagnostic uint8 + +// constants that define BFDDiagnostic flags +const ( + BFDDiagnosticNone BFDDiagnostic = 0 // No Diagnostic + BFDDiagnosticTimeExpired BFDDiagnostic = 1 // Control Detection Time Expired + BFDDiagnosticEchoFailed BFDDiagnostic = 2 // Echo Function Failed + BFDDiagnosticNeighborSignalDown BFDDiagnostic = 3 // Neighbor Signaled Session Down + BFDDiagnosticForwardPlaneReset BFDDiagnostic = 4 // Forwarding Plane Reset + BFDDiagnosticPathDown BFDDiagnostic = 5 // Path Down + BFDDiagnosticConcatPathDown BFDDiagnostic = 6 // Concatenated Path Down + BFDDiagnosticAdminDown BFDDiagnostic = 7 // Administratively Down + BFDDiagnosticRevConcatPathDown BFDDiagnostic = 8 // Reverse Concatenated Path Dow +) + +// String returns a string version of BFDDiagnostic +func (bd BFDDiagnostic) String() string { + switch bd { + default: + return "Unknown" + case BFDDiagnosticNone: + return "None" + case BFDDiagnosticTimeExpired: + return "Control Detection Time Expired" + case BFDDiagnosticEchoFailed: + return "Echo Function Failed" + case BFDDiagnosticNeighborSignalDown: + return "Neighbor Signaled Session Down" + case BFDDiagnosticForwardPlaneReset: + return "Forwarding Plane Reset" + case BFDDiagnosticPathDown: + return "Path Down" + case BFDDiagnosticConcatPathDown: + return "Concatenated Path Down" + case BFDDiagnosticAdminDown: + return "Administratively Down" + case BFDDiagnosticRevConcatPathDown: + return "Reverse Concatenated Path Down" + } +} + +// BFDState represents the state of a BFD session +type BFDState uint8 + +// constants that define BFDState +const ( + BFDStateAdminDown BFDState = 0 + BFDStateDown BFDState = 1 + BFDStateInit BFDState = 2 + BFDStateUp BFDState = 3 +) + +// String returns a string version of BFDState +func (s BFDState) String() string { + switch s { + default: + return "Unknown" + case BFDStateAdminDown: + return "Admin Down" + case BFDStateDown: + return "Down" + case BFDStateInit: + return "Init" + case BFDStateUp: + return "Up" + } +} + +// BFDDetectMultiplier represents the negotiated transmit interval, +// multiplied by this value, provides the Detection Time for the +// receiving system in Asynchronous mode. +type BFDDetectMultiplier uint8 + +// BFDDiscriminator is a unique, nonzero discriminator value used +// to demultiplex multiple BFD sessions between the same pair of systems. +type BFDDiscriminator uint32 + +// BFDTimeInterval represents a time interval in microseconds +type BFDTimeInterval uint32 + +// BFDAuthType represents the authentication used in the BFD session +type BFDAuthType uint8 + +// constants that define the BFDAuthType +const ( + BFDAuthTypeNone BFDAuthType = 0 // No Auth + BFDAuthTypePassword BFDAuthType = 1 // Simple Password + BFDAuthTypeKeyedMD5 BFDAuthType = 2 // Keyed MD5 + BFDAuthTypeMeticulousKeyedMD5 BFDAuthType = 3 // Meticulous Keyed MD5 + BFDAuthTypeKeyedSHA1 BFDAuthType = 4 // Keyed SHA1 + BFDAuthTypeMeticulousKeyedSHA1 BFDAuthType = 5 // Meticulous Keyed SHA1 +) + +// String returns a string version of BFDAuthType +func (at BFDAuthType) String() string { + switch at { + default: + return "Unknown" + case BFDAuthTypeNone: + return "No Authentication" + case BFDAuthTypePassword: + return "Simple Password" + case BFDAuthTypeKeyedMD5: + return "Keyed MD5" + case BFDAuthTypeMeticulousKeyedMD5: + return "Meticulous Keyed MD5" + case BFDAuthTypeKeyedSHA1: + return "Keyed SHA1" + case BFDAuthTypeMeticulousKeyedSHA1: + return "Meticulous Keyed SHA1" + } +} + +// BFDAuthKeyID represents the authentication key ID in use for +// this packet. This allows multiple keys to be active simultaneously. +type BFDAuthKeyID uint8 + +// BFDAuthSequenceNumber represents the sequence number for this packet. +// For Keyed Authentication, this value is incremented occasionally. For +// Meticulous Keyed Authentication, this value is incremented for each +// successive packet transmitted for a session. This provides protection +// against replay attacks. +type BFDAuthSequenceNumber uint32 + +// BFDAuthData represents the authentication key or digest +type BFDAuthData []byte + +// BFDAuthHeader represents authentication data used in the BFD session +type BFDAuthHeader struct { + AuthType BFDAuthType + KeyID BFDAuthKeyID + SequenceNumber BFDAuthSequenceNumber + Data BFDAuthData +} + +// Length returns the data length of the BFDAuthHeader based on the +// authentication type +func (h *BFDAuthHeader) Length() int { + switch h.AuthType { + case BFDAuthTypePassword: + return 3 + len(h.Data) + case BFDAuthTypeKeyedMD5, BFDAuthTypeMeticulousKeyedMD5: + return 8 + len(h.Data) + case BFDAuthTypeKeyedSHA1, BFDAuthTypeMeticulousKeyedSHA1: + return 8 + len(h.Data) + default: + return 0 + } +} + +// BFD represents a BFD control message packet whose payload contains +// the control information required to for a BFD session. +// +// References +// ---------- +// +// Wikipedia's BFD entry: +// https://en.wikipedia.org/wiki/Bidirectional_Forwarding_Detection +// This is the best place to get an overview of BFD. +// +// RFC 5880 "Bidirectional Forwarding Detection (BFD)" (2010) +// https://tools.ietf.org/html/rfc5880 +// This is the original BFD specification. +// +// RFC 5881 "Bidirectional Forwarding Detection (BFD) for IPv4 and IPv6 (Single Hop)" (2010) +// https://tools.ietf.org/html/rfc5881 +// Describes the use of the Bidirectional Forwarding Detection (BFD) +// protocol over IPv4 and IPv6 for single IP hops. +type BFD struct { + BaseLayer // Stores the packet bytes and payload bytes. + + Version BFDVersion // Version of the BFD protocol. + Diagnostic BFDDiagnostic // Diagnostic code for last state change + State BFDState // Current state + Poll bool // Requesting verification + Final bool // Responding to a received BFD Control packet that had the Poll (P) bit set. + ControlPlaneIndependent bool // BFD implementation does not share fate with its control plane + AuthPresent bool // Authentication Section is present and the session is to be authenticated + Demand bool // Demand mode is active + Multipoint bool // For future point-to-multipoint extensions. Must always be zero + DetectMultiplier BFDDetectMultiplier // Detection time multiplier + MyDiscriminator BFDDiscriminator // A unique, nonzero discriminator value + YourDiscriminator BFDDiscriminator // discriminator received from the remote system. + DesiredMinTxInterval BFDTimeInterval // Minimum interval, in microseconds, the local system would like to use when transmitting BFD Control packets + RequiredMinRxInterval BFDTimeInterval // Minimum interval, in microseconds, between received BFD Control packets that this system is capable of supporting + RequiredMinEchoRxInterval BFDTimeInterval // Minimum interval, in microseconds, between received BFD Echo packets that this system is capable of supporting + AuthHeader *BFDAuthHeader // Authentication data, variable length. +} + +// Length returns the data length of a BFD Control message which +// changes based on the presence and type of authentication +// contained in the message +func (d *BFD) Length() int { + if d.AuthPresent && (d.AuthHeader != nil) { + return bfdMinimumRecordSizeInBytes + d.AuthHeader.Length() + } + + return bfdMinimumRecordSizeInBytes +} + +// LayerType returns the layer type of the BFD object, which is LayerTypeBFD. +func (d *BFD) LayerType() gopacket.LayerType { + return LayerTypeBFD +} + +// decodeBFD analyses a byte slice and attempts to decode it as a BFD +// control packet +// +// If it succeeds, it loads p with information about the packet and returns nil. +// If it fails, it returns an error (non nil). +// +// This function is employed in layertypes.go to register the BFD layer. +func decodeBFD(data []byte, p gopacket.PacketBuilder) error { + + // Attempt to decode the byte slice. + d := &BFD{} + err := d.DecodeFromBytes(data, p) + if err != nil { + return err + } + + // If the decoding worked, add the layer to the packet and set it + // as the application layer too, if there isn't already one. + p.AddLayer(d) + p.SetApplicationLayer(d) + + return nil +} + +// DecodeFromBytes analyses a byte slice and attempts to decode it as a BFD +// control packet. +// +// Upon succeeds, it loads the BFD object with information about the packet +// and returns nil. +// Upon failure, it returns an error (non nil). +func (d *BFD) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + + // If the data block is too short to be a BFD record, then return an error. + if len(data) < bfdMinimumRecordSizeInBytes { + df.SetTruncated() + return errors.New("BFD packet too short") + } + + pLen := uint8(data[3]) + if len(data) != int(pLen) { + return errors.New("BFD packet length does not match") + } + + // BFD type embeds type BaseLayer which contains two fields: + // Contents is supposed to contain the bytes of the data at this level. + // Payload is supposed to contain the payload of this level. + // Here we set the baselayer to be the bytes of the BFD record. + d.BaseLayer = BaseLayer{Contents: data[:len(data)]} + + // Extract the fields from the block of bytes. + // To make sense of this, refer to the packet diagram + // above and the section on endian conventions. + + // The first few fields are all packed into the first 32 bits. Unpack them. + d.Version = BFDVersion(((data[0] & 0xE0) >> 5)) + d.Diagnostic = BFDDiagnostic(data[0] & 0x1F) + data = data[1:] + + d.State = BFDState((data[0] & 0xC0) >> 6) + d.Poll = data[0]&0x20 != 0 + d.Final = data[0]&0x10 != 0 + d.ControlPlaneIndependent = data[0]&0x08 != 0 + d.AuthPresent = data[0]&0x04 != 0 + d.Demand = data[0]&0x02 != 0 + d.Multipoint = data[0]&0x01 != 0 + data = data[1:] + + data, d.DetectMultiplier = data[1:], BFDDetectMultiplier(data[0]) + data, _ = data[1:], uint8(data[0]) // Consume length + + // The remaining fields can just be copied in big endian order. + data, d.MyDiscriminator = data[4:], BFDDiscriminator(binary.BigEndian.Uint32(data[:4])) + data, d.YourDiscriminator = data[4:], BFDDiscriminator(binary.BigEndian.Uint32(data[:4])) + data, d.DesiredMinTxInterval = data[4:], BFDTimeInterval(binary.BigEndian.Uint32(data[:4])) + data, d.RequiredMinRxInterval = data[4:], BFDTimeInterval(binary.BigEndian.Uint32(data[:4])) + data, d.RequiredMinEchoRxInterval = data[4:], BFDTimeInterval(binary.BigEndian.Uint32(data[:4])) + + if d.AuthPresent && (len(data) > 2) { + d.AuthHeader = &BFDAuthHeader{} + data, d.AuthHeader.AuthType = data[1:], BFDAuthType(data[0]) + data, _ = data[1:], uint8(data[0]) // Consume length + data, d.AuthHeader.KeyID = data[1:], BFDAuthKeyID(data[0]) + + switch d.AuthHeader.AuthType { + case BFDAuthTypePassword: + d.AuthHeader.Data = BFDAuthData(data) + case BFDAuthTypeKeyedMD5, BFDAuthTypeMeticulousKeyedMD5: + // Skipped reserved byte + data, d.AuthHeader.SequenceNumber = data[5:], BFDAuthSequenceNumber(binary.BigEndian.Uint32(data[1:5])) + d.AuthHeader.Data = BFDAuthData(data) + case BFDAuthTypeKeyedSHA1, BFDAuthTypeMeticulousKeyedSHA1: + // Skipped reserved byte + data, d.AuthHeader.SequenceNumber = data[5:], BFDAuthSequenceNumber(binary.BigEndian.Uint32(data[1:5])) + d.AuthHeader.Data = BFDAuthData(data) + } + } + + return nil +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (d *BFD) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + data, err := b.PrependBytes(bfdMinimumRecordSizeInBytes) + if err != nil { + return err + } + + // Pack the first few fields into the first 32 bits. + data[0] = byte(byte(d.Version<<5) | byte(d.Diagnostic)) + h := uint8(0) + h |= (uint8(d.State) << 6) + h |= (uint8(bool2uint8(d.Poll)) << 5) + h |= (uint8(bool2uint8(d.Final)) << 4) + h |= (uint8(bool2uint8(d.ControlPlaneIndependent)) << 3) + h |= (uint8(bool2uint8(d.AuthPresent)) << 2) + h |= (uint8(bool2uint8(d.Demand)) << 1) + h |= uint8(bool2uint8(d.Multipoint)) + data[1] = byte(h) + data[2] = byte(d.DetectMultiplier) + data[3] = byte(d.Length()) + + // The remaining fields can just be copied in big endian order. + binary.BigEndian.PutUint32(data[4:], uint32(d.MyDiscriminator)) + binary.BigEndian.PutUint32(data[8:], uint32(d.YourDiscriminator)) + binary.BigEndian.PutUint32(data[12:], uint32(d.DesiredMinTxInterval)) + binary.BigEndian.PutUint32(data[16:], uint32(d.RequiredMinRxInterval)) + binary.BigEndian.PutUint32(data[20:], uint32(d.RequiredMinEchoRxInterval)) + + if d.AuthPresent && (d.AuthHeader != nil) { + auth, err := b.AppendBytes(int(d.AuthHeader.Length())) + if err != nil { + return err + } + + auth[0] = byte(d.AuthHeader.AuthType) + auth[1] = byte(d.AuthHeader.Length()) + auth[2] = byte(d.AuthHeader.KeyID) + + switch d.AuthHeader.AuthType { + case BFDAuthTypePassword: + copy(auth[3:], d.AuthHeader.Data) + case BFDAuthTypeKeyedMD5, BFDAuthTypeMeticulousKeyedMD5: + auth[3] = byte(0) + binary.BigEndian.PutUint32(auth[4:], uint32(d.AuthHeader.SequenceNumber)) + copy(auth[8:], d.AuthHeader.Data) + case BFDAuthTypeKeyedSHA1, BFDAuthTypeMeticulousKeyedSHA1: + auth[3] = byte(0) + binary.BigEndian.PutUint32(auth[4:], uint32(d.AuthHeader.SequenceNumber)) + copy(auth[8:], d.AuthHeader.Data) + } + } + + return nil +} + +// CanDecode returns a set of layers that BFD objects can decode. +// As BFD objects can only decide the BFD layer, we can return just that layer. +// Apparently a single layer type implements LayerClass. +func (d *BFD) CanDecode() gopacket.LayerClass { + return LayerTypeBFD +} + +// NextLayerType specifies the next layer that GoPacket should attempt to +// analyse after this (BFD) layer. As BFD packets do not contain any payload +// bytes, there are no further layers to analyse. +func (d *BFD) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypeZero +} + +// Payload returns an empty byte slice as BFD packets do not carry a payload +func (d *BFD) Payload() []byte { + return nil +} + +// bool2uint8 converts a bool to uint8 +func bool2uint8(b bool) uint8 { + if b { + return 1 + } + return 0 +} diff --git a/vendor/github.com/google/gopacket/layers/bfd_test.go b/vendor/github.com/google/gopacket/layers/bfd_test.go new file mode 100644 index 0000000..1ac84cb --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/bfd_test.go @@ -0,0 +1,289 @@ +// Copyright 2017 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. +// +//****************************************************************************** + +package layers + +import ( + "github.com/google/gopacket" + "reflect" + "testing" +) + +//****************************************************************************** + +// checkBFD() uses the bfd.go code to analyse the packet bytes as an BFD Control +// packet and generate an BFD object. It then compares the generated BFD object +// with the one provided and throws an error if there is any difference. +// The desc argument is output with any failure message to identify the test. +func checkBFD(desc string, t *testing.T, packetBytes []byte, pExpectedBFD *BFD) { + + // Analyse the packet bytes, yielding a new packet object p. + p := gopacket.NewPacket(packetBytes, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Errorf("Failed to decode packet %s: %v", desc, p.ErrorLayer().Error()) + } + + // Ensure that the packet analysis yielded the correct set of layers: + // Link Layer = Ethernet. + // Network Layer = IPv4. + // Transport Layer = UDP. + // Application Layer = BFD. + checkLayers(p, []gopacket.LayerType{ + LayerTypeEthernet, + LayerTypeIPv4, + LayerTypeUDP, + LayerTypeBFD}, t) + + // Select the Application (BFD) layer. + pResultBFD, ok := p.ApplicationLayer().(*BFD) + if !ok { + t.Error("No BFD layer type found in packet in " + desc + ".") + } + + // Compare the generated BFD object with the expected BFD object. + if !reflect.DeepEqual(pResultBFD, pExpectedBFD) { + t.Errorf("BFD packet processing failed for packet "+desc+ + ":\ngot :\n%#v\n\nwant :\n%#v\n\n", pResultBFD, pExpectedBFD) + } + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{} + err := pResultBFD.SerializeTo(buf, opts) + if err != nil { + t.Error(err) + } + if !reflect.DeepEqual(pResultBFD.Contents, buf.Bytes()) { + t.Errorf("BFD packet serialization failed for packet "+desc+ + ":\ngot :\n%+v\n\nwant :\n%+v\n\n", buf.Bytes(), pResultBFD.Contents) + } + +} + +func TestBFDNoAuth(t *testing.T) { + // This test packet is based off of the first BFD packet in the BFD sample capture + // pcap file bfd-raw-auth-simple.pcap on the Wireshark sample captures page: + // + // https://wiki.wireshark.org/SampleCaptures + // https://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=get&target=bfd-raw-auth-simple.pcap + // + // Changed to remove the authentication header, and adjust all of the lengths + var testPacketBFD = []byte{ + 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x10, 0x94, 0x00, 0x00, 0x02, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x11, 0x2f, 0x58, 0xc0, 0x55, 0x01, 0x02, 0xc0, 0x00, + 0x00, 0x01, 0xc0, 0x00, 0x0e, 0xc8, 0x00, 0x20, 0x72, 0x31, 0x20, 0x40, 0x05, 0x18, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x40, 0x00, 0x0f, 0x42, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x4e, 0x0a, 0x90, 0x40, + } + + // Assemble the BFD object that we expect to emerge from this test. + pExpectedBFD := &BFD{ + BaseLayer: BaseLayer{ + Contents: []byte{ + 0x20, 0x40, 0x05, 0x18, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x40, + 0x00, 0x0f, 0x42, 0x40, 0x00, 0x00, 0x00, 0x00, + }, + Payload: nil, + }, + Version: 1, + Diagnostic: BFDDiagnosticNone, + State: BFDStateDown, + Poll: false, + Final: false, + ControlPlaneIndependent: false, + AuthPresent: false, + Demand: false, + Multipoint: false, + DetectMultiplier: 5, + MyDiscriminator: 1, + YourDiscriminator: 0, + DesiredMinTxInterval: 1000000, + RequiredMinRxInterval: 1000000, + RequiredMinEchoRxInterval: 0, + AuthHeader: nil, + } + + checkBFD("testNoAuth", t, testPacketBFD, pExpectedBFD) +} + +//****************************************************************************** + +func TestBFDAuthTypePassword(t *testing.T) { + + // This test packet is the first BFD packet in the BFD sample capture + // pcap file bfd-raw-auth-simple.pcap on the Wireshark sample captures page: + // + // https://wiki.wireshark.org/SampleCaptures + // https://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=get&target=bfd-raw-auth-simple.pcap + var testPacketBFD = []byte{ + 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x10, 0x94, 0x00, 0x00, 0x02, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x11, 0x2f, 0x58, 0xc0, 0x55, 0x01, 0x02, 0xc0, 0x00, + 0x00, 0x01, 0xc0, 0x00, 0x0e, 0xc8, 0x00, 0x29, 0x72, 0x31, 0x20, 0x44, 0x05, 0x21, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x40, 0x00, 0x0f, 0x42, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x09, 0x02, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4e, 0x0a, 0x90, 0x40, + } + + // Assemble the BFD object that we expect to emerge from this test. + pExpectedBFD := &BFD{ + BaseLayer: BaseLayer{ + Contents: []byte{ + 0x20, 0x44, 0x05, 0x21, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x40, + 0x00, 0x0f, 0x42, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x09, 0x02, 0x73, 0x65, 0x63, 0x72, 0x65, + 0x74, + }, + Payload: nil, + }, + Version: 1, + Diagnostic: BFDDiagnosticNone, + State: BFDStateDown, + Poll: false, + Final: false, + ControlPlaneIndependent: false, + AuthPresent: true, + Demand: false, + Multipoint: false, + DetectMultiplier: 5, + MyDiscriminator: 1, + YourDiscriminator: 0, + DesiredMinTxInterval: 1000000, + RequiredMinRxInterval: 1000000, + RequiredMinEchoRxInterval: 0, + AuthHeader: &BFDAuthHeader{ + AuthType: BFDAuthTypePassword, + KeyID: 2, + SequenceNumber: 0, + Data: []byte{'s', 'e', 'c', 'r', 'e', 't'}, + }, + } + + checkBFD("testBFDAuthTypePassword", t, testPacketBFD, pExpectedBFD) +} + +//****************************************************************************** + +func TestBFDAuthTypeKeyedMD5(t *testing.T) { + + // This test packet is the first BFD packet in the BFD sample capture + // pcap file bfd-raw-auth-md5.pcap on the Wireshark sample captures page: + // + // https://wiki.wireshark.org/SampleCaptures + // https://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=get&target=bfd-raw-auth-md5.pcap + var testPacketBFD = []byte{ + 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x10, 0x94, 0x00, 0x00, 0x02, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x11, 0x2f, 0x48, 0xc0, 0x55, 0x01, 0x02, 0xc0, 0x00, + 0x00, 0x01, 0x04, 0x00, 0x0e, 0xc8, 0x00, 0x38, 0x6a, 0xcc, 0x20, 0x44, 0x05, 0x30, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x40, 0x00, 0x0f, 0x42, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x18, 0x02, 0x00, 0x00, 0x00, 0x00, 0x05, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x3c, 0xc3, 0xf8, 0x21, + } + + // Assemble the BFD object that we expect to emerge from this test. + pExpectedBFD := &BFD{ + BaseLayer: BaseLayer{ + Contents: []byte{ + 0x20, 0x44, 0x05, 0x30, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x40, + 0x00, 0x0f, 0x42, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x18, 0x02, 0x00, 0x00, 0x00, 0x00, 0x05, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + }, + Payload: nil, + }, + Version: 1, + Diagnostic: BFDDiagnosticNone, + State: BFDStateDown, + Poll: false, + Final: false, + ControlPlaneIndependent: false, + AuthPresent: true, + Demand: false, + Multipoint: false, + DetectMultiplier: 5, + MyDiscriminator: 1, + YourDiscriminator: 0, + DesiredMinTxInterval: 1000000, + RequiredMinRxInterval: 1000000, + RequiredMinEchoRxInterval: 0, + AuthHeader: &BFDAuthHeader{ + AuthType: BFDAuthTypeKeyedMD5, + KeyID: 2, + SequenceNumber: 5, + Data: []byte{ + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + }, + }, + } + + checkBFD("testBFDAuthTypeKeyedMD5", t, testPacketBFD, pExpectedBFD) +} + +//****************************************************************************** + +func TestBFDAuthTypeMeticulousKeyedSHA1(t *testing.T) { + + // This test packet is the first BFD packet in the BFD sample capture + // pcap file bfd-raw-auth-sha1.pcap on the Wireshark sample captures page: + // + // https://wiki.wireshark.org/SampleCaptures + // https://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=get&target=bfd-raw-auth-sha1.pcap + var testPacketBFD = []byte{ + 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x10, 0x94, 0x00, 0x00, 0x02, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x11, 0x2f, 0x45, 0xc0, 0x55, 0x01, 0x02, 0xc0, 0x00, + 0x00, 0x01, 0x04, 0x00, 0x0e, 0xc8, 0x00, 0x3c, 0x37, 0x8a, 0x20, 0x44, 0x05, 0x34, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x40, 0x00, 0x0f, 0x42, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x1c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x05, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0xea, 0x6d, + 0x1f, 0x21, + } + + // Assemble the BFD object that we expect to emerge from this test. + pExpectedBFD := &BFD{ + BaseLayer: BaseLayer{ + Contents: []byte{ + 0x20, 0x44, 0x05, 0x34, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x40, + 0x00, 0x0f, 0x42, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x1c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x05, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x1a, + }, + Payload: nil, + }, + Version: 1, + Diagnostic: BFDDiagnosticNone, + State: BFDStateDown, + Poll: false, + Final: false, + ControlPlaneIndependent: false, + AuthPresent: true, + Demand: false, + Multipoint: false, + DetectMultiplier: 5, + MyDiscriminator: 1, + YourDiscriminator: 0, + DesiredMinTxInterval: 1000000, + RequiredMinRxInterval: 1000000, + RequiredMinEchoRxInterval: 0, + AuthHeader: &BFDAuthHeader{ + AuthType: BFDAuthTypeMeticulousKeyedSHA1, + KeyID: 2, + SequenceNumber: 5, + Data: []byte{ + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x1a, + }, + }, + } + + checkBFD("TestBFDAuthTypeMeticulousKeyedSHA1", t, testPacketBFD, pExpectedBFD) +} diff --git a/vendor/github.com/google/gopacket/layers/cdp.go b/vendor/github.com/google/gopacket/layers/cdp.go new file mode 100644 index 0000000..d67203e --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/cdp.go @@ -0,0 +1,651 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +// Enum types courtesy of... +// http://search.cpan.org/~mchapman/Net-CDP-0.09/lib/Net/CDP.pm +// https://code.google.com/p/ladvd/ +// http://anonsvn.wireshark.org/viewvc/releases/wireshark-1.8.6/epan/dissectors/packet-cdp.c + +package layers + +import ( + "encoding/binary" + "fmt" + "net" + + "github.com/google/gopacket" +) + +// CDPTLVType is the type of each TLV value in a CiscoDiscovery packet. +type CDPTLVType uint16 + +// CDPTLVType values. +const ( + CDPTLVDevID CDPTLVType = 0x0001 + CDPTLVAddress CDPTLVType = 0x0002 + CDPTLVPortID CDPTLVType = 0x0003 + CDPTLVCapabilities CDPTLVType = 0x0004 + CDPTLVVersion CDPTLVType = 0x0005 + CDPTLVPlatform CDPTLVType = 0x0006 + CDPTLVIPPrefix CDPTLVType = 0x0007 + CDPTLVHello CDPTLVType = 0x0008 + CDPTLVVTPDomain CDPTLVType = 0x0009 + CDPTLVNativeVLAN CDPTLVType = 0x000a + CDPTLVFullDuplex CDPTLVType = 0x000b + CDPTLVVLANReply CDPTLVType = 0x000e + CDPTLVVLANQuery CDPTLVType = 0x000f + CDPTLVPower CDPTLVType = 0x0010 + CDPTLVMTU CDPTLVType = 0x0011 + CDPTLVExtendedTrust CDPTLVType = 0x0012 + CDPTLVUntrustedCOS CDPTLVType = 0x0013 + CDPTLVSysName CDPTLVType = 0x0014 + CDPTLVSysOID CDPTLVType = 0x0015 + CDPTLVMgmtAddresses CDPTLVType = 0x0016 + CDPTLVLocation CDPTLVType = 0x0017 + CDPTLVExternalPortID CDPTLVType = 0x0018 + CDPTLVPowerRequested CDPTLVType = 0x0019 + CDPTLVPowerAvailable CDPTLVType = 0x001a + CDPTLVPortUnidirectional CDPTLVType = 0x001b + CDPTLVEnergyWise CDPTLVType = 0x001d + CDPTLVSparePairPOE CDPTLVType = 0x001f +) + +// CiscoDiscoveryValue is a TLV value inside a CiscoDiscovery packet layer. +type CiscoDiscoveryValue struct { + Type CDPTLVType + Length uint16 + Value []byte +} + +// CiscoDiscovery is a packet layer containing the Cisco Discovery Protocol. +// See http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm#31885 +type CiscoDiscovery struct { + BaseLayer + Version byte + TTL byte + Checksum uint16 + Values []CiscoDiscoveryValue +} + +// CDPCapability is the set of capabilities advertised by a CDP device. +type CDPCapability uint32 + +// CDPCapability values. +const ( + CDPCapMaskRouter CDPCapability = 0x0001 + CDPCapMaskTBBridge CDPCapability = 0x0002 + CDPCapMaskSPBridge CDPCapability = 0x0004 + CDPCapMaskSwitch CDPCapability = 0x0008 + CDPCapMaskHost CDPCapability = 0x0010 + CDPCapMaskIGMPFilter CDPCapability = 0x0020 + CDPCapMaskRepeater CDPCapability = 0x0040 + CDPCapMaskPhone CDPCapability = 0x0080 + CDPCapMaskRemote CDPCapability = 0x0100 +) + +// CDPCapabilities represents the capabilities of a device +type CDPCapabilities struct { + L3Router bool + TBBridge bool + SPBridge bool + L2Switch bool + IsHost bool + IGMPFilter bool + L1Repeater bool + IsPhone bool + RemotelyManaged bool +} + +// CDP Power-over-Ethernet values. +const ( + CDPPoEFourWire byte = 0x01 + CDPPoEPDArch byte = 0x02 + CDPPoEPDRequest byte = 0x04 + CDPPoEPSE byte = 0x08 +) + +// CDPSparePairPoE provides information on PoE. +type CDPSparePairPoE struct { + PSEFourWire bool // Supported / Not supported + PDArchShared bool // Shared / Independent + PDRequestOn bool // On / Off + PSEOn bool // On / Off +} + +// CDPVLANDialogue encapsulates a VLAN Query/Reply +type CDPVLANDialogue struct { + ID uint8 + VLAN uint16 +} + +// CDPPowerDialogue encapsulates a Power Query/Reply +type CDPPowerDialogue struct { + ID uint16 + MgmtID uint16 + Values []uint32 +} + +// CDPLocation provides location information for a CDP device. +type CDPLocation struct { + Type uint8 // Undocumented + Location string +} + +// CDPHello is a Cisco Hello message (undocumented, hence the "Unknown" fields) +type CDPHello struct { + OUI []byte + ProtocolID uint16 + ClusterMaster net.IP + Unknown1 net.IP + Version byte + SubVersion byte + Status byte + Unknown2 byte + ClusterCommander net.HardwareAddr + SwitchMAC net.HardwareAddr + Unknown3 byte + ManagementVLAN uint16 +} + +// CDPEnergyWiseSubtype is used within CDP to define TLV values. +type CDPEnergyWiseSubtype uint32 + +// CDPEnergyWiseSubtype values. +const ( + CDPEnergyWiseRole CDPEnergyWiseSubtype = 0x00000007 + CDPEnergyWiseDomain CDPEnergyWiseSubtype = 0x00000008 + CDPEnergyWiseName CDPEnergyWiseSubtype = 0x00000009 + CDPEnergyWiseReplyTo CDPEnergyWiseSubtype = 0x00000017 +) + +// CDPEnergyWise is used by CDP to monitor and control power usage. +type CDPEnergyWise struct { + EncryptedData []byte + Unknown1 uint32 + SequenceNumber uint32 + ModelNumber string + Unknown2 uint16 + HardwareID string + SerialNum string + Unknown3 []byte + Role string + Domain string + Name string + ReplyUnknown1 []byte + ReplyPort []byte + ReplyAddress []byte + ReplyUnknown2 []byte + ReplyUnknown3 []byte +} + +// CiscoDiscoveryInfo represents the decoded details for a set of CiscoDiscoveryValues +type CiscoDiscoveryInfo struct { + BaseLayer + CDPHello + DeviceID string + Addresses []net.IP + PortID string + Capabilities CDPCapabilities + Version string + Platform string + IPPrefixes []net.IPNet + VTPDomain string + NativeVLAN uint16 + FullDuplex bool + VLANReply CDPVLANDialogue + VLANQuery CDPVLANDialogue + PowerConsumption uint16 + MTU uint32 + ExtendedTrust uint8 + UntrustedCOS uint8 + SysName string + SysOID string + MgmtAddresses []net.IP + Location CDPLocation + PowerRequest CDPPowerDialogue + PowerAvailable CDPPowerDialogue + SparePairPoe CDPSparePairPoE + EnergyWise CDPEnergyWise + Unknown []CiscoDiscoveryValue +} + +// LayerType returns gopacket.LayerTypeCiscoDiscovery. +func (c *CiscoDiscovery) LayerType() gopacket.LayerType { + return LayerTypeCiscoDiscovery +} + +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)) +} + +// LayerType returns gopacket.LayerTypeCiscoDiscoveryInfo. +func (c *CiscoDiscoveryInfo) LayerType() gopacket.LayerType { + return LayerTypeCiscoDiscoveryInfo +} + +func decodeCiscoDiscoveryTLVs(data []byte) (values []CiscoDiscoveryValue, err error) { + for len(data) > 0 { + val := CiscoDiscoveryValue{ + Type: CDPTLVType(binary.BigEndian.Uint16(data[:2])), + Length: binary.BigEndian.Uint16(data[2:4]), + } + if val.Length < 4 { + err = fmt.Errorf("Invalid CiscoDiscovery value length %d", val.Length) + break + } + val.Value = data[4:val.Length] + values = append(values, val) + data = data[val.Length:] + } + return +} + +func decodeCiscoDiscoveryInfo(data []byte, p gopacket.PacketBuilder) error { + var err error + info := &CiscoDiscoveryInfo{BaseLayer: BaseLayer{Contents: data}} + p.AddLayer(info) + values, err := decodeCiscoDiscoveryTLVs(data) + if err != nil { // Unlikely, as parent decode will fail, but better safe... + return err + } + for _, val := range values { + switch val.Type { + case CDPTLVDevID: + info.DeviceID = string(val.Value) + case CDPTLVAddress: + if err = checkCDPTLVLen(val, 4); err != nil { + return err + } + info.Addresses, err = decodeAddresses(val.Value) + if err != nil { + return err + } + case CDPTLVPortID: + info.PortID = string(val.Value) + case CDPTLVCapabilities: + if err = checkCDPTLVLen(val, 4); err != nil { + return err + } + val := CDPCapability(binary.BigEndian.Uint32(val.Value[0:4])) + info.Capabilities.L3Router = (val&CDPCapMaskRouter > 0) + info.Capabilities.TBBridge = (val&CDPCapMaskTBBridge > 0) + info.Capabilities.SPBridge = (val&CDPCapMaskSPBridge > 0) + info.Capabilities.L2Switch = (val&CDPCapMaskSwitch > 0) + info.Capabilities.IsHost = (val&CDPCapMaskHost > 0) + info.Capabilities.IGMPFilter = (val&CDPCapMaskIGMPFilter > 0) + info.Capabilities.L1Repeater = (val&CDPCapMaskRepeater > 0) + info.Capabilities.IsPhone = (val&CDPCapMaskPhone > 0) + info.Capabilities.RemotelyManaged = (val&CDPCapMaskRemote > 0) + case CDPTLVVersion: + info.Version = string(val.Value) + case CDPTLVPlatform: + info.Platform = string(val.Value) + case CDPTLVIPPrefix: + v := val.Value + l := len(v) + if l%5 == 0 && l >= 5 { + for len(v) > 0 { + _, ipnet, _ := net.ParseCIDR(fmt.Sprintf("%d.%d.%d.%d/%d", v[0], v[1], v[2], v[3], v[4])) + info.IPPrefixes = append(info.IPPrefixes, *ipnet) + v = v[5:] + } + } else { + return fmt.Errorf("Invalid TLV %v length %d", val.Type, len(val.Value)) + } + case CDPTLVHello: + if err = checkCDPTLVLen(val, 32); err != nil { + return err + } + v := val.Value + info.CDPHello.OUI = v[0:3] + info.CDPHello.ProtocolID = binary.BigEndian.Uint16(v[3:5]) + info.CDPHello.ClusterMaster = v[5:9] + info.CDPHello.Unknown1 = v[9:13] + info.CDPHello.Version = v[13] + info.CDPHello.SubVersion = v[14] + info.CDPHello.Status = v[15] + info.CDPHello.Unknown2 = v[16] + info.CDPHello.ClusterCommander = v[17:23] + info.CDPHello.SwitchMAC = v[23:29] + info.CDPHello.Unknown3 = v[29] + info.CDPHello.ManagementVLAN = binary.BigEndian.Uint16(v[30:32]) + case CDPTLVVTPDomain: + info.VTPDomain = string(val.Value) + case CDPTLVNativeVLAN: + if err = checkCDPTLVLen(val, 2); err != nil { + return err + } + info.NativeVLAN = binary.BigEndian.Uint16(val.Value[0:2]) + case CDPTLVFullDuplex: + if err = checkCDPTLVLen(val, 1); err != nil { + return err + } + info.FullDuplex = (val.Value[0] == 1) + case CDPTLVVLANReply: + if err = checkCDPTLVLen(val, 3); err != nil { + return err + } + info.VLANReply.ID = uint8(val.Value[0]) + info.VLANReply.VLAN = binary.BigEndian.Uint16(val.Value[1:3]) + case CDPTLVVLANQuery: + if err = checkCDPTLVLen(val, 3); err != nil { + return err + } + info.VLANQuery.ID = uint8(val.Value[0]) + info.VLANQuery.VLAN = binary.BigEndian.Uint16(val.Value[1:3]) + case CDPTLVPower: + if err = checkCDPTLVLen(val, 2); err != nil { + return err + } + info.PowerConsumption = binary.BigEndian.Uint16(val.Value[0:2]) + case CDPTLVMTU: + if err = checkCDPTLVLen(val, 4); err != nil { + return err + } + info.MTU = binary.BigEndian.Uint32(val.Value[0:4]) + case CDPTLVExtendedTrust: + if err = checkCDPTLVLen(val, 1); err != nil { + return err + } + info.ExtendedTrust = uint8(val.Value[0]) + case CDPTLVUntrustedCOS: + if err = checkCDPTLVLen(val, 1); err != nil { + return err + } + info.UntrustedCOS = uint8(val.Value[0]) + case CDPTLVSysName: + info.SysName = string(val.Value) + case CDPTLVSysOID: + info.SysOID = string(val.Value) + case CDPTLVMgmtAddresses: + if err = checkCDPTLVLen(val, 4); err != nil { + return err + } + info.MgmtAddresses, err = decodeAddresses(val.Value) + if err != nil { + return err + } + case CDPTLVLocation: + if err = checkCDPTLVLen(val, 2); err != nil { + return err + } + info.Location.Type = uint8(val.Value[0]) + info.Location.Location = string(val.Value[1:]) + + // case CDPTLVLExternalPortID: + // Undocumented + case CDPTLVPowerRequested: + if err = checkCDPTLVLen(val, 4); err != nil { + return err + } + info.PowerRequest.ID = binary.BigEndian.Uint16(val.Value[0:2]) + info.PowerRequest.MgmtID = binary.BigEndian.Uint16(val.Value[2:4]) + for n := 4; n < len(val.Value); n += 4 { + info.PowerRequest.Values = append(info.PowerRequest.Values, binary.BigEndian.Uint32(val.Value[n:n+4])) + } + case CDPTLVPowerAvailable: + if err = checkCDPTLVLen(val, 4); err != nil { + return err + } + info.PowerAvailable.ID = binary.BigEndian.Uint16(val.Value[0:2]) + info.PowerAvailable.MgmtID = binary.BigEndian.Uint16(val.Value[2:4]) + for n := 4; n < len(val.Value); n += 4 { + info.PowerAvailable.Values = append(info.PowerAvailable.Values, binary.BigEndian.Uint32(val.Value[n:n+4])) + } + // case CDPTLVPortUnidirectional + // Undocumented + case CDPTLVEnergyWise: + if err = checkCDPTLVLen(val, 72); err != nil { + return err + } + info.EnergyWise.EncryptedData = val.Value[0:20] + info.EnergyWise.Unknown1 = binary.BigEndian.Uint32(val.Value[20:24]) + info.EnergyWise.SequenceNumber = binary.BigEndian.Uint32(val.Value[24:28]) + info.EnergyWise.ModelNumber = string(val.Value[28:44]) + info.EnergyWise.Unknown2 = binary.BigEndian.Uint16(val.Value[44:46]) + info.EnergyWise.HardwareID = string(val.Value[46:49]) + info.EnergyWise.SerialNum = string(val.Value[49:60]) + info.EnergyWise.Unknown3 = val.Value[60:68] + tlvLen := binary.BigEndian.Uint16(val.Value[68:70]) + tlvNum := binary.BigEndian.Uint16(val.Value[70:72]) + data := val.Value[72:] + if len(data) < int(tlvLen) { + return fmt.Errorf("Invalid TLV length %d vs %d", tlvLen, len(data)) + } + numSeen := 0 + for len(data) > 8 { + numSeen++ + if numSeen > int(tlvNum) { // Too many TLV's ? + return fmt.Errorf("Too many TLV's - wanted %d, saw %d", tlvNum, numSeen) + } + tType := CDPEnergyWiseSubtype(binary.BigEndian.Uint32(data[0:4])) + tLen := int(binary.BigEndian.Uint32(data[4:8])) + if tLen > len(data)-8 { + return fmt.Errorf("Invalid TLV length %d vs %d", tLen, len(data)-8) + } + data = data[8:] + switch tType { + case CDPEnergyWiseRole: + info.EnergyWise.Role = string(data[:]) + case CDPEnergyWiseDomain: + info.EnergyWise.Domain = string(data[:]) + case CDPEnergyWiseName: + info.EnergyWise.Name = string(data[:]) + case CDPEnergyWiseReplyTo: + if len(data) >= 18 { + info.EnergyWise.ReplyUnknown1 = data[0:2] + info.EnergyWise.ReplyPort = data[2:4] + info.EnergyWise.ReplyAddress = data[4:8] + info.EnergyWise.ReplyUnknown2 = data[8:10] + info.EnergyWise.ReplyUnknown3 = data[10:14] + } + } + data = data[tLen:] + } + case CDPTLVSparePairPOE: + if err = checkCDPTLVLen(val, 1); err != nil { + return err + } + v := val.Value[0] + info.SparePairPoe.PSEFourWire = (v&CDPPoEFourWire > 0) + info.SparePairPoe.PDArchShared = (v&CDPPoEPDArch > 0) + info.SparePairPoe.PDRequestOn = (v&CDPPoEPDRequest > 0) + info.SparePairPoe.PSEOn = (v&CDPPoEPSE > 0) + default: + info.Unknown = append(info.Unknown, val) + } + } + return nil +} + +// CDP Protocol Types +const ( + CDPProtocolTypeNLPID byte = 1 + CDPProtocolType802_2 byte = 2 +) + +// CDPAddressType is used to define TLV values within CDP addresses. +type CDPAddressType uint64 + +// CDP Address types. +const ( + CDPAddressTypeCLNP CDPAddressType = 0x81 + CDPAddressTypeIPV4 CDPAddressType = 0xcc + CDPAddressTypeIPV6 CDPAddressType = 0xaaaa030000000800 + CDPAddressTypeDECNET CDPAddressType = 0xaaaa030000006003 + CDPAddressTypeAPPLETALK CDPAddressType = 0xaaaa03000000809b + CDPAddressTypeIPX CDPAddressType = 0xaaaa030000008137 + CDPAddressTypeVINES CDPAddressType = 0xaaaa0300000080c4 + CDPAddressTypeXNS CDPAddressType = 0xaaaa030000000600 + CDPAddressTypeAPOLLO CDPAddressType = 0xaaaa030000008019 +) + +func decodeAddresses(v []byte) (addresses []net.IP, err error) { + numaddr := int(binary.BigEndian.Uint32(v[0:4])) + if numaddr < 1 { + return nil, fmt.Errorf("Invalid Address TLV number %d", numaddr) + } + v = v[4:] + if len(v) < numaddr*8 { + return nil, fmt.Errorf("Invalid Address TLV length %d", len(v)) + } + for i := 0; i < numaddr; i++ { + prottype := v[0] + if prottype != CDPProtocolTypeNLPID && prottype != CDPProtocolType802_2 { // invalid protocol type + return nil, fmt.Errorf("Invalid Address Protocol %d", prottype) + } + protlen := int(v[1]) + if (prottype == CDPProtocolTypeNLPID && protlen != 1) || + (prottype == CDPProtocolType802_2 && protlen != 3 && protlen != 8) { // invalid length + return nil, fmt.Errorf("Invalid Address Protocol length %d", protlen) + } + plen := make([]byte, 8) + copy(plen[8-protlen:], v[2:2+protlen]) + protocol := CDPAddressType(binary.BigEndian.Uint64(plen)) + v = v[2+protlen:] + addrlen := binary.BigEndian.Uint16(v[0:2]) + ab := v[2 : 2+addrlen] + if protocol == CDPAddressTypeIPV4 && addrlen == 4 { + addresses = append(addresses, net.IPv4(ab[0], ab[1], ab[2], ab[3])) + } else if protocol == CDPAddressTypeIPV6 && addrlen == 16 { + addresses = append(addresses, net.IP(ab)) + } else { + // only handle IPV4 & IPV6 for now + } + v = v[2+addrlen:] + if len(v) < 8 { + break + } + } + return +} + +func (t CDPTLVType) String() (s string) { + switch t { + case CDPTLVDevID: + s = "Device ID" + case CDPTLVAddress: + s = "Addresses" + case CDPTLVPortID: + s = "Port ID" + case CDPTLVCapabilities: + s = "Capabilities" + case CDPTLVVersion: + s = "Software Version" + case CDPTLVPlatform: + s = "Platform" + case CDPTLVIPPrefix: + s = "IP Prefix" + case CDPTLVHello: + s = "Protocol Hello" + case CDPTLVVTPDomain: + s = "VTP Management Domain" + case CDPTLVNativeVLAN: + s = "Native VLAN" + case CDPTLVFullDuplex: + s = "Full Duplex" + case CDPTLVVLANReply: + s = "VoIP VLAN Reply" + case CDPTLVVLANQuery: + s = "VLANQuery" + case CDPTLVPower: + s = "Power consumption" + case CDPTLVMTU: + s = "MTU" + case CDPTLVExtendedTrust: + s = "Extended Trust Bitmap" + case CDPTLVUntrustedCOS: + s = "Untrusted Port CoS" + case CDPTLVSysName: + s = "System Name" + case CDPTLVSysOID: + s = "System OID" + case CDPTLVMgmtAddresses: + s = "Management Addresses" + case CDPTLVLocation: + s = "Location" + case CDPTLVExternalPortID: + s = "External Port ID" + case CDPTLVPowerRequested: + s = "Power Requested" + case CDPTLVPowerAvailable: + s = "Power Available" + case CDPTLVPortUnidirectional: + s = "Port Unidirectional" + case CDPTLVEnergyWise: + s = "Energy Wise" + case CDPTLVSparePairPOE: + s = "Spare Pair POE" + default: + s = "Unknown" + } + return +} + +func (a CDPAddressType) String() (s string) { + switch a { + case CDPAddressTypeCLNP: + s = "Connectionless Network Protocol" + case CDPAddressTypeIPV4: + s = "IPv4" + case CDPAddressTypeIPV6: + s = "IPv6" + case CDPAddressTypeDECNET: + s = "DECnet Phase IV" + case CDPAddressTypeAPPLETALK: + s = "Apple Talk" + case CDPAddressTypeIPX: + s = "Novell IPX" + case CDPAddressTypeVINES: + s = "Banyan VINES" + case CDPAddressTypeXNS: + s = "Xerox Network Systems" + case CDPAddressTypeAPOLLO: + s = "Apollo" + default: + s = "Unknown" + } + return +} + +func (t CDPEnergyWiseSubtype) String() (s string) { + switch t { + case CDPEnergyWiseRole: + s = "Role" + case CDPEnergyWiseDomain: + s = "Domain" + case CDPEnergyWiseName: + s = "Name" + case CDPEnergyWiseReplyTo: + s = "ReplyTo" + default: + s = "Unknown" + } + return +} + +func checkCDPTLVLen(v CiscoDiscoveryValue, l int) (err error) { + if len(v.Value) < l { + err = fmt.Errorf("Invalid TLV %v length %d", v.Type, len(v.Value)) + } + return +} diff --git a/vendor/github.com/google/gopacket/layers/ctp.go b/vendor/github.com/google/gopacket/layers/ctp.go new file mode 100644 index 0000000..8287584 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/ctp.go @@ -0,0 +1,109 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "fmt" + "github.com/google/gopacket" +) + +// EthernetCTPFunction is the function code used by the EthernetCTP protocol to identify each +// EthernetCTP layer. +type EthernetCTPFunction uint16 + +// EthernetCTPFunction values. +const ( + EthernetCTPFunctionReply EthernetCTPFunction = 1 + EthernetCTPFunctionForwardData EthernetCTPFunction = 2 +) + +// EthernetCTP implements the EthernetCTP protocol, see http://www.mit.edu/people/jhawk/ctp.html. +// We split EthernetCTP up into the top-level EthernetCTP layer, followed by zero or more +// EthernetCTPForwardData layers, followed by a final EthernetCTPReply layer. +type EthernetCTP struct { + BaseLayer + SkipCount uint16 +} + +// LayerType returns gopacket.LayerTypeEthernetCTP. +func (c *EthernetCTP) LayerType() gopacket.LayerType { + return LayerTypeEthernetCTP +} + +// EthernetCTPForwardData is the ForwardData layer inside EthernetCTP. See EthernetCTP's docs for more +// details. +type EthernetCTPForwardData struct { + BaseLayer + Function EthernetCTPFunction + ForwardAddress []byte +} + +// LayerType returns gopacket.LayerTypeEthernetCTPForwardData. +func (c *EthernetCTPForwardData) LayerType() gopacket.LayerType { + return LayerTypeEthernetCTPForwardData +} + +// ForwardEndpoint returns the EthernetCTPForwardData ForwardAddress as an endpoint. +func (c *EthernetCTPForwardData) ForwardEndpoint() gopacket.Endpoint { + return gopacket.NewEndpoint(EndpointMAC, c.ForwardAddress) +} + +// EthernetCTPReply is the Reply layer inside EthernetCTP. See EthernetCTP's docs for more details. +type EthernetCTPReply struct { + BaseLayer + Function EthernetCTPFunction + ReceiptNumber uint16 + Data []byte +} + +// LayerType returns gopacket.LayerTypeEthernetCTPReply. +func (c *EthernetCTPReply) LayerType() gopacket.LayerType { + return LayerTypeEthernetCTPReply +} + +// Payload returns the EthernetCTP reply's Data bytes. +func (c *EthernetCTPReply) Payload() []byte { return c.Data } + +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)) +} + +// 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) +} diff --git a/vendor/github.com/google/gopacket/layers/decode_test.go b/vendor/github.com/google/gopacket/layers/decode_test.go new file mode 100644 index 0000000..ecfbff7 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/decode_test.go @@ -0,0 +1,1234 @@ +// Copyright 2012, Google, Inc. All rights reserved. +// Copyright 2009-2011 Andreas Krennmair. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "bytes" + "encoding/hex" + "fmt" + "net" + "reflect" + "strings" + "testing" + + "github.com/google/gopacket" + "github.com/google/gopacket/bytediff" +) + +var testSimpleTCPPacket = []byte{ + 0x00, 0x00, 0x0c, 0x9f, 0xf0, 0x20, 0xbc, 0x30, 0x5b, 0xe8, 0xd3, 0x49, + 0x08, 0x00, 0x45, 0x00, 0x01, 0xa4, 0x39, 0xdf, 0x40, 0x00, 0x40, 0x06, + 0x55, 0x5a, 0xac, 0x11, 0x51, 0x49, 0xad, 0xde, 0xfe, 0xe1, 0xc5, 0xf7, + 0x00, 0x50, 0xc5, 0x7e, 0x0e, 0x48, 0x49, 0x07, 0x42, 0x32, 0x80, 0x18, + 0x00, 0x73, 0x9a, 0x8f, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x03, 0x77, + 0x37, 0x9c, 0x42, 0x77, 0x5e, 0x3a, 0x47, 0x45, 0x54, 0x20, 0x2f, 0x20, + 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, + 0x73, 0x74, 0x3a, 0x20, 0x77, 0x77, 0x77, 0x2e, 0x66, 0x69, 0x73, 0x68, + 0x2e, 0x63, 0x6f, 0x6d, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x6b, 0x65, 0x65, 0x70, 0x2d, 0x61, + 0x6c, 0x69, 0x76, 0x65, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, + 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, + 0x61, 0x2f, 0x35, 0x2e, 0x30, 0x20, 0x28, 0x58, 0x31, 0x31, 0x3b, 0x20, + 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20, 0x78, 0x38, 0x36, 0x5f, 0x36, 0x34, + 0x29, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x57, 0x65, 0x62, 0x4b, 0x69, + 0x74, 0x2f, 0x35, 0x33, 0x35, 0x2e, 0x32, 0x20, 0x28, 0x4b, 0x48, 0x54, + 0x4d, 0x4c, 0x2c, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x47, 0x65, 0x63, + 0x6b, 0x6f, 0x29, 0x20, 0x43, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x2f, 0x31, + 0x35, 0x2e, 0x30, 0x2e, 0x38, 0x37, 0x34, 0x2e, 0x31, 0x32, 0x31, 0x20, + 0x53, 0x61, 0x66, 0x61, 0x72, 0x69, 0x2f, 0x35, 0x33, 0x35, 0x2e, 0x32, + 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x74, 0x65, + 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x61, 0x70, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, 0x68, 0x74, 0x6d, + 0x6c, 0x2b, 0x78, 0x6d, 0x6c, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, 0x6d, 0x6c, 0x3b, 0x71, 0x3d, + 0x30, 0x2e, 0x39, 0x2c, 0x2a, 0x2f, 0x2a, 0x3b, 0x71, 0x3d, 0x30, 0x2e, + 0x38, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x45, 0x6e, + 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x67, 0x7a, 0x69, 0x70, + 0x2c, 0x64, 0x65, 0x66, 0x6c, 0x61, 0x74, 0x65, 0x2c, 0x73, 0x64, 0x63, + 0x68, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x4c, 0x61, + 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3a, 0x20, 0x65, 0x6e, 0x2d, 0x55, + 0x53, 0x2c, 0x65, 0x6e, 0x3b, 0x71, 0x3d, 0x30, 0x2e, 0x38, 0x0d, 0x0a, + 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x43, 0x68, 0x61, 0x72, 0x73, + 0x65, 0x74, 0x3a, 0x20, 0x49, 0x53, 0x4f, 0x2d, 0x38, 0x38, 0x35, 0x39, + 0x2d, 0x31, 0x2c, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x3b, 0x71, 0x3d, 0x30, + 0x2e, 0x37, 0x2c, 0x2a, 0x3b, 0x71, 0x3d, 0x30, 0x2e, 0x33, 0x0d, 0x0a, + 0x0d, 0x0a, +} + +var testDecodeOptions = gopacket.DecodeOptions{ + SkipDecodeRecovery: true, +} + +// Benchmarks for actual gopacket code + +func BenchmarkLayerClassSliceContains(b *testing.B) { + lc := gopacket.NewLayerClassSlice([]gopacket.LayerType{LayerTypeTCP, LayerTypeEthernet}) + for i := 0; i < b.N; i++ { + _ = lc.Contains(LayerTypeTCP) + } +} + +func BenchmarkLayerClassMapContains(b *testing.B) { + lc := gopacket.NewLayerClassMap([]gopacket.LayerType{LayerTypeTCP, LayerTypeEthernet}) + for i := 0; i < b.N; i++ { + _ = lc.Contains(LayerTypeTCP) + } +} + +func BenchmarkLazyNoCopyEthLayer(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testSimpleTCPPacket, LinkTypeEthernet, gopacket.DecodeOptions{Lazy: true, NoCopy: true}).Layer(LayerTypeEthernet) + } +} + +func BenchmarkLazyNoCopyIPLayer(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testSimpleTCPPacket, LinkTypeEthernet, gopacket.DecodeOptions{Lazy: true, NoCopy: true}).Layer(LayerTypeIPv4) + } +} + +func BenchmarkLazyNoCopyTCPLayer(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testSimpleTCPPacket, LinkTypeEthernet, gopacket.DecodeOptions{Lazy: true, NoCopy: true}).Layer(LayerTypeTCP) + } +} + +func BenchmarkLazyNoCopyAllLayers(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testSimpleTCPPacket, LinkTypeEthernet, gopacket.DecodeOptions{Lazy: true, NoCopy: true}).Layers() + } +} + +func BenchmarkDefault(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testSimpleTCPPacket, LinkTypeEthernet, gopacket.Default) + } +} + +func getSerializeLayers() []gopacket.SerializableLayer { + p := gopacket.NewPacket(testSimpleTCPPacket, LinkTypeEthernet, testDecodeOptions) + slayers := []gopacket.SerializableLayer{} + for _, l := range p.Layers() { + slayers = append(slayers, l.(gopacket.SerializableLayer)) + } + p.Layer(LayerTypeTCP).(*TCP).SetNetworkLayerForChecksum( + p.NetworkLayer()) + return slayers +} + +func BenchmarkSerializeTcpNoOptions(b *testing.B) { + slayers := getSerializeLayers() + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{} + for i := 0; i < b.N; i++ { + gopacket.SerializeLayers(buf, opts, slayers...) + } +} + +func BenchmarkSerializeTcpFixLengths(b *testing.B) { + slayers := getSerializeLayers() + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{FixLengths: true} + for i := 0; i < b.N; i++ { + gopacket.SerializeLayers(buf, opts, slayers...) + } +} + +func BenchmarkSerializeTcpComputeChecksums(b *testing.B) { + slayers := getSerializeLayers() + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{ComputeChecksums: true} + for i := 0; i < b.N; i++ { + gopacket.SerializeLayers(buf, opts, slayers...) + } +} + +func BenchmarkSerializeTcpFixLengthsComputeChecksums(b *testing.B) { + slayers := getSerializeLayers() + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{FixLengths: true, ComputeChecksums: true} + for i := 0; i < b.N; i++ { + gopacket.SerializeLayers(buf, opts, slayers...) + } +} + +func BenchmarkLazy(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testSimpleTCPPacket, LinkTypeEthernet, gopacket.Lazy) + } +} + +func BenchmarkNoCopy(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testSimpleTCPPacket, LinkTypeEthernet, gopacket.NoCopy) + } +} + +func BenchmarkLazyNoCopy(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testSimpleTCPPacket, LinkTypeEthernet, gopacket.DecodeOptions{Lazy: true, NoCopy: true}) + } +} + +func BenchmarkKnownStack(b *testing.B) { + stack := []gopacket.DecodingLayer{&Ethernet{}, &IPv4{}, &TCP{}, &gopacket.Payload{}} + nf := gopacket.NilDecodeFeedback + for i := 0; i < b.N; i++ { + data := testSimpleTCPPacket[:] + for _, d := range stack { + _ = d.DecodeFromBytes(data, nf) + data = d.LayerPayload() + } + } +} + +func BenchmarkDecodingLayerParserIgnorePanic(b *testing.B) { + decoded := make([]gopacket.LayerType, 0, 20) + dlp := gopacket.NewDecodingLayerParser(LayerTypeEthernet, &Ethernet{}, &IPv4{}, &TCP{}, &gopacket.Payload{}) + dlp.IgnorePanic = true + for i := 0; i < b.N; i++ { + dlp.DecodeLayers(testSimpleTCPPacket, &decoded) + } +} + +func BenchmarkDecodingLayerParserHandlePanic(b *testing.B) { + decoded := make([]gopacket.LayerType, 0, 20) + dlp := gopacket.NewDecodingLayerParser(LayerTypeEthernet, &Ethernet{}, &IPv4{}, &TCP{}, &gopacket.Payload{}) + dlp.IgnorePanic = false + for i := 0; i < b.N; i++ { + dlp.DecodeLayers(testSimpleTCPPacket, &decoded) + } +} + +func BenchmarkAlloc(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = &TCP{} + } +} + +func BenchmarkFlow(b *testing.B) { + p := gopacket.NewPacket(testSimpleTCPPacket, LinkTypeEthernet, gopacket.DecodeOptions{Lazy: true, NoCopy: true}) + net := p.NetworkLayer() + for i := 0; i < b.N; i++ { + net.NetworkFlow() + } +} + +func BenchmarkEndpoints(b *testing.B) { + p := gopacket.NewPacket(testSimpleTCPPacket, LinkTypeEthernet, gopacket.DecodeOptions{Lazy: true, NoCopy: true}) + flow := p.NetworkLayer().NetworkFlow() + for i := 0; i < b.N; i++ { + flow.Endpoints() + } +} + +func BenchmarkTCPLayerFromDecodedPacket(b *testing.B) { + b.StopTimer() + p := gopacket.NewPacket(testSimpleTCPPacket, LinkTypeEthernet, testDecodeOptions) + b.StartTimer() + for i := 0; i < b.N; i++ { + _ = p.Layer(LayerTypeTCP) + } +} + +func BenchmarkTCPLayerClassFromDecodedPacket(b *testing.B) { + b.StopTimer() + p := gopacket.NewPacket(testSimpleTCPPacket, LinkTypeEthernet, testDecodeOptions) + lc := gopacket.NewLayerClass([]gopacket.LayerType{LayerTypeTCP}) + b.StartTimer() + for i := 0; i < b.N; i++ { + _ = p.LayerClass(lc) + } +} + +func BenchmarkTCPTransportLayerFromDecodedPacket(b *testing.B) { + b.StopTimer() + p := gopacket.NewPacket(testSimpleTCPPacket, LinkTypeEthernet, testDecodeOptions) + b.StartTimer() + for i := 0; i < b.N; i++ { + _ = p.TransportLayer() + } +} + +func testDecoder([]byte, gopacket.PacketBuilder) error { + return nil +} + +func BenchmarkDecodeFuncCallOverheadDirectCall(b *testing.B) { + var data []byte + var pb gopacket.PacketBuilder + for i := 0; i < b.N; i++ { + _ = testDecoder(data, pb) + } +} + +func BenchmarkDecodeFuncCallOverheadDecoderCall(b *testing.B) { + d := gopacket.DecodeFunc(testDecoder) + var data []byte + var pb gopacket.PacketBuilder + for i := 0; i < b.N; i++ { + _ = d.Decode(data, pb) + } +} + +func BenchmarkDecodeFuncCallOverheadArrayCall(b *testing.B) { + EthernetTypeMetadata[1] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(testDecoder)} + d := EthernetType(1) + var data []byte + var pb gopacket.PacketBuilder + for i := 0; i < b.N; i++ { + _ = d.Decode(data, pb) + } +} + +func BenchmarkFmtVerboseString(b *testing.B) { + b.StopTimer() + p := gopacket.NewPacket(testSimpleTCPPacket, LinkTypeEthernet, testDecodeOptions) + b.StartTimer() + for i := 0; i < b.N; i++ { + _ = fmt.Sprintf("%#v", p) + } +} + +func BenchmarkPacketString(b *testing.B) { + b.StopTimer() + p := gopacket.NewPacket(testSimpleTCPPacket, LinkTypeEthernet, testDecodeOptions) + b.StartTimer() + for i := 0; i < b.N; i++ { + _ = p.String() + } +} + +func BenchmarkPacketDumpString(b *testing.B) { + b.StopTimer() + p := gopacket.NewPacket(testSimpleTCPPacket, LinkTypeEthernet, testDecodeOptions) + b.StartTimer() + for i := 0; i < b.N; i++ { + _ = p.String() + } +} + +// TestFlowMapKey makes sure a flow and an endpoint can be used as map keys. +func TestFlowMapKey(t *testing.T) { + _ = map[gopacket.Flow]bool{} + _ = map[gopacket.Endpoint]bool{} + _ = map[[2]gopacket.Flow]bool{} +} + +func TestDecodeSimpleTCPPacket(t *testing.T) { + equal := func(desc, want string, got fmt.Stringer) { + if want != got.String() { + t.Errorf("%s: got %q want %q", desc, got.String(), want) + } + } + p := gopacket.NewPacket(testSimpleTCPPacket, LinkTypeEthernet, gopacket.DecodeOptions{Lazy: true, NoCopy: true}) + if eth := p.LinkLayer(); eth == nil { + t.Error("No ethernet layer found") + } else { + equal("Eth Src", "bc:30:5b:e8:d3:49", eth.LinkFlow().Src()) + equal("Eth Dst", "00:00:0c:9f:f0:20", eth.LinkFlow().Dst()) + } + if net := p.NetworkLayer(); net == nil { + t.Error("No net layer found") + } else if ip, ok := net.(*IPv4); !ok { + t.Error("Net layer is not IP layer") + } else { + equal("IP Src", "172.17.81.73", net.NetworkFlow().Src()) + equal("IP Dst", "173.222.254.225", net.NetworkFlow().Dst()) + want := &IPv4{ + BaseLayer: BaseLayer{testSimpleTCPPacket[14:34], testSimpleTCPPacket[34:]}, + Version: 4, + IHL: 5, + TOS: 0, + Length: 420, + Id: 14815, + Flags: 0x02, + FragOffset: 0, + TTL: 64, + Protocol: 6, + Checksum: 0x555A, + SrcIP: []byte{172, 17, 81, 73}, + DstIP: []byte{173, 222, 254, 225}, + } + if !reflect.DeepEqual(ip, want) { + t.Errorf("IP layer mismatch, \ngot %#v\nwant %#v\n", ip, want) + } + } + if trans := p.TransportLayer(); trans == nil { + t.Error("No transport layer found") + } else if tcp, ok := trans.(*TCP); !ok { + t.Error("Transport layer is not TCP layer") + } else { + equal("TCP Src", "50679", trans.TransportFlow().Src()) + equal("TCP Dst", "80", trans.TransportFlow().Dst()) + want := &TCP{ + BaseLayer: BaseLayer{testSimpleTCPPacket[34:66], testSimpleTCPPacket[66:]}, + SrcPort: 50679, + DstPort: 80, + Seq: 0xc57e0e48, + Ack: 0x49074232, + DataOffset: 8, + ACK: true, + PSH: true, + Window: 0x73, + Checksum: 0x9a8f, + Urgent: 0, + sPort: []byte{0xc5, 0xf7}, + dPort: []byte{0x0, 0x50}, + Options: []TCPOption{ + TCPOption{ + OptionType: 0x1, + OptionLength: 0x1, + }, + TCPOption{ + OptionType: 0x1, + OptionLength: 0x1, + }, + TCPOption{ + OptionType: 0x8, + OptionLength: 0xa, + OptionData: []byte{0x3, 0x77, 0x37, 0x9c, 0x42, 0x77, 0x5e, 0x3a}, + }, + }, + opts: [4]TCPOption{ + TCPOption{ + OptionType: 0x1, + OptionLength: 0x1, + }, + TCPOption{ + OptionType: 0x1, + OptionLength: 0x1, + }, + TCPOption{ + OptionType: 0x8, + OptionLength: 0xa, + OptionData: []byte{0x3, 0x77, 0x37, 0x9c, 0x42, 0x77, 0x5e, 0x3a}, + }, + TCPOption{}, + }, + } + if !reflect.DeepEqual(tcp, want) { + t.Errorf("TCP layer mismatch\ngot %#v\nwant %#v", tcp, want) + } + } + if payload, ok := p.Layer(gopacket.LayerTypePayload).(*gopacket.Payload); payload == nil || !ok { + t.Error("No payload layer found") + } else { + if string(payload.Payload()) != "GET / HTTP/1.1\r\nHost: www.fish.com\r\nConnection: keep-alive\r\nUser-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.121 Safari/535.2\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\nAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\r\n\r\n" { + t.Error("--- Payload STRING ---\n", string(payload.Payload()), "\n--- Payload BYTES ---\n", payload.Payload()) + } + } + + // Test re-serialization. + testSerialization(t, p, testSimpleTCPPacket) +} + +type canSetNetLayer interface { + SetNetworkLayerForChecksum(gopacket.NetworkLayer) error +} + +func testSerialization(t *testing.T, p gopacket.Packet, data []byte) { + for _, opts := range []gopacket.SerializeOptions{ + gopacket.SerializeOptions{}, + gopacket.SerializeOptions{FixLengths: true}, + gopacket.SerializeOptions{ComputeChecksums: true}, + gopacket.SerializeOptions{FixLengths: true, ComputeChecksums: true}, + } { + testSerializationWithOpts(t, p, data, opts) + } +} + +func testSerializationWithOpts(t *testing.T, p gopacket.Packet, data []byte, opts gopacket.SerializeOptions) { + // Test re-serialization. + slayers := []gopacket.SerializableLayer{} + for _, l := range p.Layers() { + slayers = append(slayers, l.(gopacket.SerializableLayer)) + if h, ok := l.(canSetNetLayer); ok { + if err := h.SetNetworkLayerForChecksum(p.NetworkLayer()); err != nil { + t.Fatal("can't set network layer:", err) + } + } + } + buf := gopacket.NewSerializeBuffer() + err := gopacket.SerializeLayers(buf, opts, slayers...) + if err != nil { + t.Errorf("unable to reserialize layers with opts %#v: %v", opts, err) + } else if !bytes.Equal(buf.Bytes(), data) { + t.Errorf("serialization failure with opts %#v:\n---want---\n%v\n---got---\n%v\nBASH-colorized diff, want->got:\n%v\n\n---PACKET---\n%v", + opts, hex.Dump(data), hex.Dump(buf.Bytes()), bytediff.BashOutput.String(bytediff.Diff(data, buf.Bytes())), p) + } +} + +// Makes sure packet payload doesn't display the 6 trailing null of this packet +// as part of the payload. They're actually the ethernet trailer. +func TestDecodeSmallTCPPacketHasEmptyPayload(t *testing.T) { + smallPacket := []byte{ + 0xbc, 0x30, 0x5b, 0xe8, 0xd3, 0x49, 0xb8, 0xac, 0x6f, 0x92, 0xd5, 0xbf, + 0x08, 0x00, 0x45, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40, 0x00, 0x40, 0x06, + 0x3f, 0x9f, 0xac, 0x11, 0x51, 0xc5, 0xac, 0x11, 0x51, 0x49, 0x00, 0x63, + 0x9a, 0xef, 0x00, 0x00, 0x00, 0x00, 0x2e, 0xc1, 0x27, 0x83, 0x50, 0x14, + 0x00, 0x00, 0xc3, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + } + p := gopacket.NewPacket(smallPacket, LinkTypeEthernet, testDecodeOptions) + + if payload := p.Layer(gopacket.LayerTypePayload); payload != nil { + t.Error("Payload found for empty TCP packet") + } + + testSerialization(t, p, smallPacket) +} + +func TestDecodeVLANPacket(t *testing.T) { + p := gopacket.NewPacket( + []byte{ + 0x00, 0x10, 0xdb, 0xff, 0x10, 0x00, 0x00, 0x15, 0x2c, 0x9d, 0xcc, 0x00, + 0x81, 0x00, 0x01, 0xf7, 0x08, 0x00, 0x45, 0x00, 0x00, 0x28, 0x29, 0x8d, + 0x40, 0x00, 0x7d, 0x06, 0x83, 0xa0, 0xac, 0x1b, 0xca, 0x8e, 0x45, 0x16, + 0x94, 0xe2, 0xd4, 0x0a, 0x00, 0x50, 0xdf, 0xab, 0x9c, 0xc6, 0xcd, 0x1e, + 0xe5, 0xd1, 0x50, 0x10, 0x01, 0x00, 0x5a, 0x74, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + }, LinkTypeEthernet, testDecodeOptions) + if err := p.ErrorLayer(); err != nil { + t.Error("Error while parsing vlan packet:", err) + } + if vlan := p.Layer(LayerTypeDot1Q); vlan == nil { + t.Error("Didn't detect vlan") + } else if _, ok := vlan.(*Dot1Q); !ok { + t.Error("LayerTypeDot1Q layer is not a Dot1Q object") + } + for i, l := range p.Layers() { + t.Logf("Layer %d: %#v", i, l) + } + want := []gopacket.LayerType{LayerTypeEthernet, LayerTypeDot1Q, LayerTypeIPv4, LayerTypeTCP} + checkLayers(p, want, t) +} + +func TestDecodeSCTPPackets(t *testing.T) { + sctpPackets := [][]byte{ + []byte{ // INIT + 0x00, 0x00, 0x0c, 0x9f, 0xf0, 0x1f, 0x24, 0xbe, 0x05, 0x27, 0x0b, 0x17, 0x08, 0x00, 0x45, 0x02, + 0x00, 0x44, 0x00, 0x00, 0x40, 0x00, 0x40, 0x84, 0xc4, 0x22, 0xac, 0x1d, 0x14, 0x0f, 0xac, 0x19, + 0x09, 0xcc, 0x27, 0x0f, 0x22, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x19, 0x6b, 0x0b, 0x40, 0x01, 0x00, + 0x00, 0x24, 0xb6, 0x96, 0xb0, 0x9e, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x0a, 0xff, 0xff, 0xdb, 0x85, + 0x60, 0x23, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x00, 0x04, 0xc0, 0x00, + 0x00, 0x04, + }, []byte{ // INIT ACK + 0x24, 0xbe, 0x05, 0x27, 0x0b, 0x17, 0x00, 0x1f, 0xca, 0xb3, 0x76, 0x40, 0x08, 0x00, 0x45, 0x20, + 0x01, 0x24, 0x00, 0x00, 0x40, 0x00, 0x36, 0x84, 0xcd, 0x24, 0xac, 0x19, 0x09, 0xcc, 0xac, 0x1d, + 0x14, 0x0f, 0x22, 0xb8, 0x27, 0x0f, 0xb6, 0x96, 0xb0, 0x9e, 0x4b, 0xab, 0x40, 0x9a, 0x02, 0x00, + 0x01, 0x04, 0x32, 0x80, 0xfb, 0x42, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x85, 0x98, + 0xb1, 0x26, 0x00, 0x07, 0x00, 0xe8, 0xd3, 0x08, 0xce, 0xe2, 0x52, 0x95, 0xcc, 0x09, 0xa1, 0x4c, + 0x6f, 0xa7, 0x9e, 0xba, 0x03, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xfb, 0x80, 0x32, 0x9e, 0xb0, + 0x96, 0xb6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x46, 0xc2, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x5e, 0x25, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x26, 0xb1, + 0x98, 0x85, 0x02, 0x00, 0x27, 0x0f, 0xac, 0x1d, 0x14, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x22, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x24, 0x6a, 0x72, 0x5c, 0x1c, 0x3c, 0xaa, + 0x7a, 0xcd, 0xd3, 0x8f, 0x52, 0x78, 0x7c, 0x77, 0xfd, 0x46, 0xbd, 0x72, 0x82, 0xc1, 0x1f, 0x70, + 0x44, 0xcc, 0xc7, 0x9b, 0x9b, 0x7b, 0x13, 0x54, 0x3f, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x24, 0xb6, 0x96, + 0xb0, 0x9e, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x0a, 0xff, 0xff, 0xdb, 0x85, 0x60, 0x23, 0x00, 0x0c, + 0x00, 0x06, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x00, 0x04, 0xc0, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x04, 0xc0, 0x00, + 0x00, 0x04, + }, []byte{ // COOKIE ECHO, DATA + 0x00, 0x00, 0x0c, 0x9f, 0xf0, 0x1f, 0x24, 0xbe, 0x05, 0x27, 0x0b, 0x17, 0x08, 0x00, 0x45, 0x02, + 0x01, 0x20, 0x00, 0x00, 0x40, 0x00, 0x40, 0x84, 0xc3, 0x46, 0xac, 0x1d, 0x14, 0x0f, 0xac, 0x19, + 0x09, 0xcc, 0x27, 0x0f, 0x22, 0xb8, 0x32, 0x80, 0xfb, 0x42, 0x01, 0xf9, 0xf3, 0xa9, 0x0a, 0x00, + 0x00, 0xe8, 0xd3, 0x08, 0xce, 0xe2, 0x52, 0x95, 0xcc, 0x09, 0xa1, 0x4c, 0x6f, 0xa7, 0x9e, 0xba, + 0x03, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xfb, 0x80, 0x32, 0x9e, 0xb0, 0x96, 0xb6, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x46, 0xc2, 0x50, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x25, + 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x26, 0xb1, 0x98, 0x85, 0x02, 0x00, + 0x27, 0x0f, 0xac, 0x1d, 0x14, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x22, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x02, 0x00, 0x24, 0x6a, 0x72, 0x5c, 0x1c, 0x3c, 0xaa, 0x7a, 0xcd, 0xd3, 0x8f, + 0x52, 0x78, 0x7c, 0x77, 0xfd, 0x46, 0xbd, 0x72, 0x82, 0xc1, 0x1f, 0x70, 0x44, 0xcc, 0xc7, 0x9b, + 0x9b, 0x7b, 0x13, 0x54, 0x3f, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x24, 0xb6, 0x96, 0xb0, 0x9e, 0x00, 0x01, + 0xc0, 0x00, 0x00, 0x0a, 0xff, 0xff, 0xdb, 0x85, 0x60, 0x23, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x05, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x04, 0xc0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x16, 0xdb, 0x85, 0x60, 0x23, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x6f, 0x6f, 0x21, 0x0a, 0x00, 0x00, 0x00, + }, []byte{ // COOKIE ACK, SACK + 0x24, 0xbe, 0x05, 0x27, 0x0b, 0x17, 0x00, 0x1f, 0xca, 0xb3, 0x76, 0x40, 0x08, 0x00, 0x45, 0x20, + 0x00, 0x34, 0x00, 0x00, 0x40, 0x00, 0x36, 0x84, 0xce, 0x14, 0xac, 0x19, 0x09, 0xcc, 0xac, 0x1d, + 0x14, 0x0f, 0x22, 0xb8, 0x27, 0x0f, 0xb6, 0x96, 0xb0, 0x9e, 0xed, 0x64, 0x30, 0x98, 0x0b, 0x00, + 0x00, 0x04, 0x03, 0x00, 0x00, 0x10, 0xdb, 0x85, 0x60, 0x23, 0x00, 0x00, 0xf3, 0xfa, 0x00, 0x00, + 0x00, 0x00, + }, []byte{ // DATA + 0x00, 0x00, 0x0c, 0x9f, 0xf0, 0x1f, 0x24, 0xbe, 0x05, 0x27, 0x0b, 0x17, 0x08, 0x00, 0x45, 0x02, + 0x00, 0x3c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x84, 0xc4, 0x2a, 0xac, 0x1d, 0x14, 0x0f, 0xac, 0x19, + 0x09, 0xcc, 0x27, 0x0f, 0x22, 0xb8, 0x32, 0x80, 0xfb, 0x42, 0xa1, 0xe3, 0xb2, 0x31, 0x00, 0x03, + 0x00, 0x19, 0xdb, 0x85, 0x60, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x62, 0x69, + 0x7a, 0x7a, 0x6c, 0x65, 0x21, 0x0a, 0x00, 0x00, 0x00, 0x00, + }, []byte{ // SACK + 0x24, 0xbe, 0x05, 0x27, 0x0b, 0x17, 0x00, 0x1f, 0xca, 0xb3, 0x76, 0x40, 0x08, 0x00, 0x45, 0x20, + 0x00, 0x30, 0x00, 0x00, 0x40, 0x00, 0x36, 0x84, 0xce, 0x18, 0xac, 0x19, 0x09, 0xcc, 0xac, 0x1d, + 0x14, 0x0f, 0x22, 0xb8, 0x27, 0x0f, 0xb6, 0x96, 0xb0, 0x9e, 0xfa, 0x49, 0x94, 0x3a, 0x03, 0x00, + 0x00, 0x10, 0xdb, 0x85, 0x60, 0x24, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, + }, []byte{ // SHUTDOWN + 0x00, 0x00, 0x0c, 0x9f, 0xf0, 0x1f, 0x24, 0xbe, 0x05, 0x27, 0x0b, 0x17, 0x08, 0x00, 0x45, 0x02, + 0x00, 0x28, 0x00, 0x00, 0x40, 0x00, 0x40, 0x84, 0xc4, 0x3e, 0xac, 0x1d, 0x14, 0x0f, 0xac, 0x19, + 0x09, 0xcc, 0x27, 0x0f, 0x22, 0xb8, 0x32, 0x80, 0xfb, 0x42, 0x3f, 0x29, 0x59, 0x23, 0x07, 0x00, + 0x00, 0x08, 0x85, 0x98, 0xb1, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, []byte{ // SHUTDOWN ACK + 0x24, 0xbe, 0x05, 0x27, 0x0b, 0x17, 0x00, 0x1f, 0xca, 0xb3, 0x76, 0x40, 0x08, 0x00, 0x45, 0x20, + 0x00, 0x24, 0x00, 0x00, 0x40, 0x00, 0x36, 0x84, 0xce, 0x24, 0xac, 0x19, 0x09, 0xcc, 0xac, 0x1d, + 0x14, 0x0f, 0x22, 0xb8, 0x27, 0x0f, 0xb6, 0x96, 0xb0, 0x9e, 0xb2, 0xc8, 0x99, 0x24, 0x08, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, []byte{ // SHUTDOWN COMPLETE + 0x00, 0x00, 0x0c, 0x9f, 0xf0, 0x1f, 0x24, 0xbe, 0x05, 0x27, 0x0b, 0x17, 0x08, 0x00, 0x45, 0x02, + 0x00, 0x24, 0x00, 0x00, 0x40, 0x00, 0x40, 0x84, 0xc4, 0x42, 0xac, 0x1d, 0x14, 0x0f, 0xac, 0x19, + 0x09, 0xcc, 0x27, 0x0f, 0x22, 0xb8, 0x32, 0x80, 0xfb, 0x42, 0xa8, 0xd1, 0x86, 0x85, 0x0e, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }} + wantLayers := [][]gopacket.LayerType{ + []gopacket.LayerType{LayerTypeSCTPInit}, + []gopacket.LayerType{LayerTypeSCTPInitAck}, + []gopacket.LayerType{LayerTypeSCTPCookieEcho, LayerTypeSCTPData, gopacket.LayerTypePayload}, + []gopacket.LayerType{LayerTypeSCTPCookieAck, LayerTypeSCTPSack}, + []gopacket.LayerType{LayerTypeSCTPData, gopacket.LayerTypePayload}, + []gopacket.LayerType{LayerTypeSCTPSack}, + []gopacket.LayerType{LayerTypeSCTPShutdown}, + []gopacket.LayerType{LayerTypeSCTPShutdownAck}, + []gopacket.LayerType{LayerTypeSCTPShutdownComplete}, + } + for i, data := range sctpPackets { + p := gopacket.NewPacket(data, LinkTypeEthernet, testDecodeOptions) + for _, typ := range wantLayers[i] { + if p.Layer(typ) == nil { + t.Errorf("Packet %d missing layer type %v, got:", i, typ) + for _, layer := range p.Layers() { + t.Errorf("\t%v", layer.LayerType()) + } + if p.ErrorLayer() != nil { + t.Error("\tPacket layer error:", p.ErrorLayer().Error()) + } + } + } + // Test re-serialization. + testSerializationWithOpts(t, p, data, gopacket.SerializeOptions{FixLengths: true, ComputeChecksums: true}) + } +} + +func TestDecodeCiscoDiscovery(t *testing.T) { + // http://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=get&target=cdp_v2.pcap + data := []byte{ + 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc, 0x00, 0x0b, 0xbe, 0x18, 0x9a, 0x41, 0x01, 0xc3, 0xaa, 0xaa, + 0x03, 0x00, 0x00, 0x0c, 0x20, 0x00, 0x02, 0xb4, 0x09, 0xa0, 0x00, 0x01, 0x00, 0x0c, 0x6d, 0x79, + 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x00, 0x02, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, + 0xcc, 0x00, 0x04, 0xc0, 0xa8, 0x00, 0xfd, 0x00, 0x03, 0x00, 0x13, 0x46, 0x61, 0x73, 0x74, 0x45, + 0x74, 0x68, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x30, 0x2f, 0x31, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x28, 0x00, 0x05, 0x01, 0x14, 0x43, 0x69, 0x73, 0x63, 0x6f, 0x20, 0x49, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6e, 0x67, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, + 0x72, 0x65, 0x20, 0x0a, 0x49, 0x4f, 0x53, 0x20, 0x28, 0x74, 0x6d, 0x29, 0x20, 0x43, 0x32, 0x39, + 0x35, 0x30, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x28, 0x43, 0x32, 0x39, + 0x35, 0x30, 0x2d, 0x49, 0x36, 0x4b, 0x32, 0x4c, 0x32, 0x51, 0x34, 0x2d, 0x4d, 0x29, 0x2c, 0x20, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x32, 0x2e, 0x31, 0x28, 0x32, 0x32, 0x29, + 0x45, 0x41, 0x31, 0x34, 0x2c, 0x20, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x20, 0x53, 0x4f, + 0x46, 0x54, 0x57, 0x41, 0x52, 0x45, 0x20, 0x28, 0x66, 0x63, 0x31, 0x29, 0x0a, 0x54, 0x65, 0x63, + 0x68, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x20, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x63, 0x69, 0x73, 0x63, 0x6f, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x65, 0x63, 0x68, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, + 0x0a, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x31, + 0x39, 0x38, 0x36, 0x2d, 0x32, 0x30, 0x31, 0x30, 0x20, 0x62, 0x79, 0x20, 0x63, 0x69, 0x73, 0x63, + 0x6f, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x0a, + 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x54, 0x75, 0x65, 0x20, 0x32, 0x36, 0x2d, + 0x4f, 0x63, 0x74, 0x2d, 0x31, 0x30, 0x20, 0x31, 0x30, 0x3a, 0x33, 0x35, 0x20, 0x62, 0x79, 0x20, + 0x6e, 0x62, 0x75, 0x72, 0x72, 0x61, 0x00, 0x06, 0x00, 0x15, 0x63, 0x69, 0x73, 0x63, 0x6f, 0x20, + 0x57, 0x53, 0x2d, 0x43, 0x32, 0x39, 0x35, 0x30, 0x2d, 0x31, 0x32, 0x00, 0x08, 0x00, 0x24, 0x00, + 0x00, 0x0c, 0x01, 0x12, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x02, 0x20, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xbe, 0x18, 0x9a, 0x40, 0xff, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x0c, 0x4d, 0x59, 0x44, 0x4f, 0x4d, 0x41, 0x49, 0x4e, 0x00, 0x0a, 0x00, 0x06, 0x00, + 0x01, 0x00, 0x0b, 0x00, 0x05, 0x01, 0x00, 0x12, 0x00, 0x05, 0x00, 0x00, 0x13, 0x00, 0x05, 0x00, + 0x00, 0x16, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0xcc, 0x00, 0x04, 0xc0, 0xa8, 0x00, + 0xfd, + } + p := gopacket.NewPacket(data, LinkTypeEthernet, testDecodeOptions) + wantLayers := []gopacket.LayerType{LayerTypeEthernet, LayerTypeLLC, LayerTypeSNAP, LayerTypeCiscoDiscovery, LayerTypeCiscoDiscoveryInfo} + checkLayers(p, wantLayers, t) + + want := &CiscoDiscoveryInfo{ + CDPHello: CDPHello{ + OUI: []byte{0, 0, 12}, + ProtocolID: 274, + ClusterMaster: []byte{0, 0, 0, 0}, + Unknown1: []byte{255, 255, 255, 255}, + Version: 1, + SubVersion: 2, + Status: 32, + Unknown2: 255, + ClusterCommander: net.HardwareAddr{0, 0, 0, 0, 0, 0}, + SwitchMAC: net.HardwareAddr{0, 0x0b, 0xbe, 0x18, 0x9a, 0x40}, + Unknown3: 255, + ManagementVLAN: 0, + }, + DeviceID: "myswitch", + Addresses: []net.IP{net.IPv4(192, 168, 0, 253)}, + PortID: "FastEthernet0/1", + Capabilities: CDPCapabilities{false, false, false, true, false, true, false, false, false}, + Version: "Cisco Internetwork Operating System Software \nIOS (tm) C2950 Software (C2950-I6K2L2Q4-M), Version 12.1(22)EA14, RELEASE SOFTWARE (fc1)\nTechnical Support: http://www.cisco.com/techsupport\nCopyright (c) 1986-2010 by cisco Systems, Inc.\nCompiled Tue 26-Oct-10 10:35 by nburra", + Platform: "cisco WS-C2950-12", + VTPDomain: "MYDOMAIN", + NativeVLAN: 1, + FullDuplex: true, + MgmtAddresses: []net.IP{net.IPv4(192, 168, 0, 253)}, + BaseLayer: BaseLayer{Contents: data[26:]}, + } + cdpL := p.Layer(LayerTypeCiscoDiscoveryInfo) + info, _ := cdpL.(*CiscoDiscoveryInfo) + if !reflect.DeepEqual(info, want) { + t.Errorf("Values mismatch, \ngot %#v\nwant %#v\n", info, want) + } +} + +func TestDecodeLinkLayerDiscovery(t *testing.T) { + // http://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=get&target=lldp.detailed.pcap + data := []byte{ + 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e, 0x00, 0x01, 0x30, 0xf9, 0xad, 0xa0, + 0x88, 0xcc, 0x02, 0x07, 0x04, 0x00, 0x01, 0x30, 0xf9, 0xad, 0xa0, 0x04, + 0x04, 0x05, 0x31, 0x2f, 0x31, 0x06, 0x02, 0x00, 0x78, 0x08, 0x17, 0x53, + 0x75, 0x6d, 0x6d, 0x69, 0x74, 0x33, 0x30, 0x30, 0x2d, 0x34, 0x38, 0x2d, + 0x50, 0x6f, 0x72, 0x74, 0x20, 0x31, 0x30, 0x30, 0x31, 0x00, 0x0a, 0x0d, + 0x53, 0x75, 0x6d, 0x6d, 0x69, 0x74, 0x33, 0x30, 0x30, 0x2d, 0x34, 0x38, + 0x00, 0x0c, 0x4c, 0x53, 0x75, 0x6d, 0x6d, 0x69, 0x74, 0x33, 0x30, 0x30, + 0x2d, 0x34, 0x38, 0x20, 0x2d, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x20, 0x37, 0x2e, 0x34, 0x65, 0x2e, 0x31, 0x20, 0x28, 0x42, 0x75, + 0x69, 0x6c, 0x64, 0x20, 0x35, 0x29, 0x20, 0x62, 0x79, 0x20, 0x52, 0x65, + 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, + 0x20, 0x30, 0x35, 0x2f, 0x32, 0x37, 0x2f, 0x30, 0x35, 0x20, 0x30, 0x34, + 0x3a, 0x35, 0x33, 0x3a, 0x31, 0x31, 0x00, 0x0e, 0x04, 0x00, 0x14, 0x00, + 0x14, 0x10, 0x0e, 0x07, 0x06, 0x00, 0x01, 0x30, 0xf9, 0xad, 0xa0, 0x02, + 0x00, 0x00, 0x03, 0xe9, 0x00, 0xfe, 0x07, 0x00, 0x12, 0x0f, 0x02, 0x07, + 0x01, 0x00, 0xfe, 0x09, 0x00, 0x12, 0x0f, 0x01, 0x03, 0x6c, 0x00, 0x00, + 0x10, 0xfe, 0x09, 0x00, 0x12, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, + 0xfe, 0x06, 0x00, 0x12, 0x0f, 0x04, 0x05, 0xf2, 0xfe, 0x06, 0x00, 0x80, + 0xc2, 0x01, 0x01, 0xe8, 0xfe, 0x07, 0x00, 0x80, 0xc2, 0x02, 0x01, 0x00, + 0x00, 0xfe, 0x17, 0x00, 0x80, 0xc2, 0x03, 0x01, 0xe8, 0x10, 0x76, 0x32, + 0x2d, 0x30, 0x34, 0x38, 0x38, 0x2d, 0x30, 0x33, 0x2d, 0x30, 0x35, 0x30, + 0x35, 0x00, 0xfe, 0x05, 0x00, 0x80, 0xc2, 0x04, 0x00, 0x00, 0x00, + } + + p := gopacket.NewPacket(data, LinkTypeEthernet, testDecodeOptions) + wantLayers := []gopacket.LayerType{LayerTypeEthernet, LayerTypeLinkLayerDiscovery, LayerTypeLinkLayerDiscoveryInfo} + checkLayers(p, wantLayers, t) + lldpL := p.Layer(LayerTypeLinkLayerDiscovery) + lldp := lldpL.(*LinkLayerDiscovery) + want := &LinkLayerDiscovery{ + ChassisID: LLDPChassisID{LLDPChassisIDSubTypeMACAddr, []byte{0x00, 0x01, 0x30, 0xf9, 0xad, 0xa0}}, + PortID: LLDPPortID{LLDPPortIDSubtypeIfaceName, []byte("1/1")}, + TTL: 120, + BaseLayer: BaseLayer{Contents: data[14:]}, + } + lldp.Values = nil // test these in next stage + if !reflect.DeepEqual(lldp, want) { + t.Errorf("Values mismatch, \ngot %#v\nwant %#v\n", lldp, want) + } + + infoL := p.Layer(LayerTypeLinkLayerDiscoveryInfo) + info := infoL.(*LinkLayerDiscoveryInfo) + wantinfo := &LinkLayerDiscoveryInfo{ + PortDescription: "Summit300-48-Port 1001\x00", + SysName: "Summit300-48\x00", + SysDescription: "Summit300-48 - Version 7.4e.1 (Build 5) by Release_Master 05/27/05 04:53:11\x00", + SysCapabilities: LLDPSysCapabilities{ + SystemCap: LLDPCapabilities{Bridge: true, Router: true}, + EnabledCap: LLDPCapabilities{Bridge: true, Router: true}, + }, + MgmtAddress: LLDPMgmtAddress{IANAAddressFamily802, []byte{0x00, 0x01, 0x30, 0xf9, 0xad, 0xa0}, LLDPInterfaceSubtypeifIndex, 1001, ""}, + OrgTLVs: []LLDPOrgSpecificTLV{ + LLDPOrgSpecificTLV{OUI: 0x120f, SubType: 0x2, Info: []uint8{0x7, 0x1, 0x0}}, + LLDPOrgSpecificTLV{OUI: 0x120f, SubType: 0x1, Info: []uint8{0x3, 0x6c, 0x0, 0x0, 0x10}}, + LLDPOrgSpecificTLV{OUI: 0x120f, SubType: 0x3, Info: []uint8{0x1, 0x0, 0x0, 0x0, 0x0}}, + LLDPOrgSpecificTLV{OUI: 0x120f, SubType: 0x4, Info: []uint8{0x5, 0xf2}}, + LLDPOrgSpecificTLV{OUI: 0x80c2, SubType: 0x1, Info: []uint8{0x1, 0xe8}}, + LLDPOrgSpecificTLV{OUI: 0x80c2, SubType: 0x2, Info: []uint8{0x1, 0x0, 0x0}}, + LLDPOrgSpecificTLV{OUI: 0x80c2, SubType: 0x3, Info: []uint8{0x1, 0xe8, 0x10, 0x76, 0x32, 0x2d, 0x30, 0x34, 0x38, 0x38, 0x2d, 0x30, 0x33, 0x2d, 0x30, 0x35, 0x30, 0x35, 0x0}}, + LLDPOrgSpecificTLV{OUI: 0x80c2, SubType: 0x4, Info: []uint8{0x0}}, + }, + Unknown: nil, + } + if !reflect.DeepEqual(info, wantinfo) { + t.Errorf("Values mismatch, \ngot %#v\nwant %#v\n", info, wantinfo) + } + info8021, err := info.Decode8021() + if err != nil { + t.Errorf("8021 Values decode error: %v", err) + } + want8021 := LLDPInfo8021{ + PVID: 488, + PPVIDs: []PortProtocolVLANID{PortProtocolVLANID{false, false, 0}}, + VLANNames: []VLANName{VLANName{488, "v2-0488-03-0505\x00"}}, + ProtocolIdentities: nil, + VIDUsageDigest: 0, + ManagementVID: 0, + LinkAggregation: LLDPLinkAggregation{false, false, 0}, + } + if !reflect.DeepEqual(info8021, want8021) { + t.Errorf("Values mismatch, \ngot %#v\nwant %#v\n", info8021, want8021) + } + info8023, err := info.Decode8023() + if err != nil { + t.Errorf("8023 Values decode error: %v", err) + } + want8023 := LLDPInfo8023{ + LinkAggregation: LLDPLinkAggregation{true, false, 0}, + MACPHYConfigStatus: LLDPMACPHYConfigStatus{true, true, 0x6c00, 0x0010}, + PowerViaMDI: LLDPPowerViaMDI8023{true, true, true, false, 1, 0, 0, 0, 0, 0, 0}, + MTU: 1522, + } + + if !reflect.DeepEqual(info8023, want8023) { + t.Errorf("Values mismatch, \ngot %#v\nwant %#v\n", info8023, want8023) + } + + // http://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=get&target=lldpmed_civicloc.pcap + data = []byte{ + 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e, 0x00, 0x13, 0x21, 0x57, 0xca, 0x7f, + 0x88, 0xcc, 0x02, 0x07, 0x04, 0x00, 0x13, 0x21, 0x57, 0xca, 0x40, 0x04, + 0x02, 0x07, 0x31, 0x06, 0x02, 0x00, 0x78, 0x08, 0x01, 0x31, 0x0a, 0x1a, + 0x50, 0x72, 0x6f, 0x43, 0x75, 0x72, 0x76, 0x65, 0x20, 0x53, 0x77, 0x69, + 0x74, 0x63, 0x68, 0x20, 0x32, 0x36, 0x30, 0x30, 0x2d, 0x38, 0x2d, 0x50, + 0x57, 0x52, 0x0c, 0x5f, 0x50, 0x72, 0x6f, 0x43, 0x75, 0x72, 0x76, 0x65, + 0x20, 0x4a, 0x38, 0x37, 0x36, 0x32, 0x41, 0x20, 0x53, 0x77, 0x69, 0x74, + 0x63, 0x68, 0x20, 0x32, 0x36, 0x30, 0x30, 0x2d, 0x38, 0x2d, 0x50, 0x57, + 0x52, 0x2c, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, + 0x48, 0x2e, 0x30, 0x38, 0x2e, 0x38, 0x39, 0x2c, 0x20, 0x52, 0x4f, 0x4d, + 0x20, 0x48, 0x2e, 0x30, 0x38, 0x2e, 0x35, 0x58, 0x20, 0x28, 0x2f, 0x73, + 0x77, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x2f, 0x62, 0x75, 0x69, 0x6c, 0x64, + 0x2f, 0x66, 0x69, 0x73, 0x68, 0x28, 0x74, 0x73, 0x5f, 0x30, 0x38, 0x5f, + 0x35, 0x29, 0x29, 0x0e, 0x04, 0x00, 0x14, 0x00, 0x04, 0x10, 0x0c, 0x05, + 0x01, 0x0f, 0xff, 0x7a, 0x94, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, + 0x09, 0x00, 0x12, 0x0f, 0x01, 0x03, 0x6c, 0x00, 0x00, 0x10, 0xfe, 0x07, + 0x00, 0x12, 0xbb, 0x01, 0x00, 0x0f, 0x04, 0xfe, 0x08, 0x00, 0x12, 0xbb, + 0x02, 0x01, 0x40, 0x65, 0xae, 0xfe, 0x2e, 0x00, 0x12, 0xbb, 0x03, 0x02, + 0x28, 0x02, 0x55, 0x53, 0x01, 0x02, 0x43, 0x41, 0x03, 0x09, 0x52, 0x6f, + 0x73, 0x65, 0x76, 0x69, 0x6c, 0x6c, 0x65, 0x06, 0x09, 0x46, 0x6f, 0x6f, + 0x74, 0x68, 0x69, 0x6c, 0x6c, 0x73, 0x13, 0x04, 0x38, 0x30, 0x30, 0x30, + 0x1a, 0x03, 0x52, 0x33, 0x4c, 0xfe, 0x07, 0x00, 0x12, 0xbb, 0x04, 0x03, + 0x00, 0x41, 0x00, 0x00, + } + + p = gopacket.NewPacket(data, LinkTypeEthernet, testDecodeOptions) + wantLayers = []gopacket.LayerType{LayerTypeEthernet, LayerTypeLinkLayerDiscovery, LayerTypeLinkLayerDiscoveryInfo} + checkLayers(p, wantLayers, t) + lldpL = p.Layer(LayerTypeLinkLayerDiscovery) + lldp = lldpL.(*LinkLayerDiscovery) + want = &LinkLayerDiscovery{ + ChassisID: LLDPChassisID{LLDPChassisIDSubTypeMACAddr, []byte{0x00, 0x13, 0x21, 0x57, 0xca, 0x40}}, + PortID: LLDPPortID{LLDPPortIDSubtypeLocal, []byte("1")}, + TTL: 120, + BaseLayer: BaseLayer{Contents: data[14:]}, + } + lldp.Values = nil // test these in next stage + if !reflect.DeepEqual(lldp, want) { + t.Errorf("Values mismatch, \ngot %#v\nwant %#v\n", lldp, want) + } + + infoL = p.Layer(LayerTypeLinkLayerDiscoveryInfo) + info = infoL.(*LinkLayerDiscoveryInfo) + wantinfo = &LinkLayerDiscoveryInfo{ + PortDescription: "1", + SysName: "ProCurve Switch 2600-8-PWR", + SysDescription: "ProCurve J8762A Switch 2600-8-PWR, revision H.08.89, ROM H.08.5X (/sw/code/build/fish(ts_08_5))", + SysCapabilities: LLDPSysCapabilities{ + SystemCap: LLDPCapabilities{Bridge: true, Router: true}, + EnabledCap: LLDPCapabilities{Bridge: true}, + }, + MgmtAddress: LLDPMgmtAddress{IANAAddressFamilyIPV4, []byte{0x0f, 0xff, 0x7a, 0x94}, LLDPInterfaceSubtypeifIndex, 0, ""}, + OrgTLVs: []LLDPOrgSpecificTLV{ + LLDPOrgSpecificTLV{OUI: 0x120f, SubType: 0x1, Info: []uint8{0x3, 0x6c, 0x0, 0x0, 0x10}}, + LLDPOrgSpecificTLV{OUI: 0x12bb, SubType: 0x1, Info: []uint8{0x0, 0xf, 0x4}}, + LLDPOrgSpecificTLV{OUI: 0x12bb, SubType: 0x2, Info: []uint8{0x1, 0x40, 0x65, 0xae}}, + LLDPOrgSpecificTLV{OUI: 0x12bb, SubType: 0x3, Info: []uint8{0x2, 0x28, 0x2, 0x55, 0x53, 0x1, 0x2, 0x43, 0x41, 0x3, 0x9, 0x52, 0x6f, 0x73, 0x65, 0x76, 0x69, 0x6c, 0x6c, 0x65, 0x6, 0x9, 0x46, 0x6f, 0x6f, 0x74, 0x68, 0x69, 0x6c, 0x6c, 0x73, 0x13, 0x4, 0x38, 0x30, 0x30, 0x30, 0x1a, 0x3, 0x52, 0x33, 0x4c}}, + LLDPOrgSpecificTLV{OUI: 0x12bb, SubType: 0x4, Info: []uint8{0x3, 0x0, 0x41}}, + }, + Unknown: nil, + } + if !reflect.DeepEqual(info, wantinfo) { + t.Errorf("Values mismatch, \ngot %#v\nwant %#v\n", info, wantinfo) + } + info8023, err = info.Decode8023() + if err != nil { + t.Errorf("8023 Values decode error: %v", err) + } + want8023 = LLDPInfo8023{ + MACPHYConfigStatus: LLDPMACPHYConfigStatus{true, true, 0x6c00, 0x0010}, + } + + if !reflect.DeepEqual(info8023, want8023) { + t.Errorf("Values mismatch, \ngot %#v\nwant %#v\n", info8023, want8023) + } + + infoMedia, err := info.DecodeMedia() + if err != nil { + t.Errorf("8023 Values decode error: %v", err) + } + wantMedia := LLDPInfoMedia{ + MediaCapabilities: LLDPMediaCapabilities{true, true, true, true, false, false, LLDPMediaClassNetwork}, + NetworkPolicy: LLDPNetworkPolicy{LLDPAppTypeVoice, true, true, 50, 6, 46}, + Location: LLDPLocation{Format: LLDPLocationFormatAddress, Address: LLDPLocationAddress{ + What: LLDPLocationAddressWhatClient, + CountryCode: "US", + AddressLines: []LLDPLocationAddressLine{ + LLDPLocationAddressLine{LLDPLocationAddressTypeNational, "CA"}, + LLDPLocationAddressLine{LLDPLocationAddressTypeCity, "Roseville"}, + LLDPLocationAddressLine{LLDPLocationAddressTypeStreet, "Foothills"}, + LLDPLocationAddressLine{LLDPLocationAddressTypeHouseNum, "8000"}, + LLDPLocationAddressLine{LLDPLocationAddressTypeUnit, "R3L"}, + }, + }}, + PowerViaMDI: LLDPPowerViaMDI{0, 0, LLDPPowerPriorityLow, 6500}, + } + + if !reflect.DeepEqual(infoMedia, wantMedia) { + t.Errorf("Values mismatch, \ngot %#v\nwant %#v\n", infoMedia, wantMedia) + } + +} + +func TestDecodeNortelDiscovery(t *testing.T) { + // http://www.thetechfirm.com/packets/nortel_btdp/btdp_nai.enc + data := []byte{ + 0x01, 0x00, 0x81, 0x00, 0x01, 0x00, 0x00, 0x04, 0x38, 0xe0, 0xcc, 0xde, + 0x00, 0x13, 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x81, 0x01, 0xa2, 0xac, 0x13, + 0x58, 0x03, 0x00, 0x04, 0x15, 0x30, 0x0c, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x38, 0xe0, 0xcc, 0xde, 0x80, 0x6a, 0x00, 0x01, 0x14, 0x00, + 0x02, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + } + p := gopacket.NewPacket(data, LinkTypeEthernet, testDecodeOptions) + wantLayers := []gopacket.LayerType{LayerTypeEthernet, LayerTypeLLC, LayerTypeSNAP, LayerTypeNortelDiscovery} + checkLayers(p, wantLayers, t) + + want := &NortelDiscovery{ + IPAddress: []byte{172, 19, 88, 3}, + SegmentID: []byte{0x00, 0x04, 0x15}, + Chassis: NDPChassisBayStack450101001000Switches, + Backplane: NDPBackplaneEthernetFastEthernetGigabitEthernet, + State: NDPStateHeartbeat, + NumLinks: 0, + } + ndpL := p.Layer(LayerTypeNortelDiscovery) + info, _ := ndpL.(*NortelDiscovery) + if !reflect.DeepEqual(info, want) { + t.Errorf("Values mismatch, \ngot %#v\nwant %#v\n", info, want) + } +} + +func TestDecodeIPv6Jumbogram(t *testing.T) { + // Haven't found any of these in the wild or on example pcaps online, so had + // to generate one myself via scapy. Unfortunately, scapy can only + // str(packet) for packets with length < 65536, due to limitations in python's + // struct library, so I generated the header with: + // Ether() / IPv6(src='::1', dst='::2') / IPv6ExtHdrHopByHop(options=[Jumbo(jumboplen=70000)]) / TCP(sport=8888, dport=80) + // then added the payload manually ("payload" * 9996). The checksums here are + // not correct, but we don't check, so who cares ;) + dataStr := "\x00\x1f\xca\xb3v@$\xbe\x05'\x0b\x17\x86\xdd`\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x06\x00\xc2\x04\x00\x01\x11p\"\xb8\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00l\xd8\x00\x00" + payload := strings.Repeat("payload", 9996) + data := []byte(dataStr + payload) + p := gopacket.NewPacket(data, LinkTypeEthernet, testDecodeOptions) + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv6, LayerTypeIPv6HopByHop, LayerTypeTCP, gopacket.LayerTypePayload}, t) + if p.ApplicationLayer() == nil { + t.Error("Packet has no application layer") + } else if string(p.ApplicationLayer().Payload()) != payload { + t.Errorf("Jumbogram payload wrong") + } + // Check truncated for jumbograms + data = data[:len(data)-1] + p = gopacket.NewPacket(data, LinkTypeEthernet, testDecodeOptions) + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv6, LayerTypeIPv6HopByHop, LayerTypeTCP, gopacket.LayerTypePayload}, t) + if !p.Metadata().Truncated { + t.Error("Jumbogram should be truncated") + } +} + +func TestDecodeUDPPacketTooSmall(t *testing.T) { + data := []byte{ + 0x00, 0x15, 0x2c, 0x9d, 0xcc, 0x00, 0x00, 0x10, 0xdb, 0xff, 0x10, 0x00, 0x81, 0x00, 0x01, 0xf7, + 0x08, 0x00, 0x45, 0x60, 0x00, 0x3c, 0x0f, 0xa9, 0x00, 0x00, 0x6e, 0x11, 0x01, 0x0a, 0x47, 0xe6, + 0xee, 0x2e, 0xac, 0x16, 0x59, 0x73, 0x00, 0x50, 0x00, 0x50, 0x00, 0x28, 0x4d, 0xad, 0x00, 0x67, + 0x00, 0x01, 0x00, 0x72, 0xd5, 0xc7, 0xf1, 0x07, 0x00, 0x00, 0x01, 0x01, 0x00, 0x0d, 0x00, 0x00, + 0x00, 0x14, 0x00, 0x00, 0x19, 0xba, + } + p := gopacket.NewPacket(data, LinkTypeEthernet, testDecodeOptions) + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeDot1Q, LayerTypeIPv4, LayerTypeUDP, gopacket.LayerTypePayload}, t) + if !p.Metadata().Truncated { + t.Error("UDP short packet should be truncated") + } +} + +func TestDecodingLayerParserFullTCPPacket(t *testing.T) { + dlp := gopacket.NewDecodingLayerParser(LayerTypeEthernet, &Ethernet{}, &IPv4{}, &TCP{}, &gopacket.Payload{}) + decoded := make([]gopacket.LayerType, 1) + err := dlp.DecodeLayers(testSimpleTCPPacket, &decoded) + if err != nil { + t.Error("Error from dlp parser: ", err) + } + if len(decoded) != 4 { + t.Error("Expected 4 layers parsed, instead got ", len(decoded)) + } +} + +// testICMP is the packet: +// 15:49:15.773265 IP 72.14.222.226 > 172.29.20.15: ICMP host 10.66.73.201 unreachable - admin prohibited filter, length 36 +// 0x0000: 24be 0527 0b17 001f cab3 75c0 0800 4500 $..'......u...E. +// 0x0010: 0038 0000 0000 fc01 d7a7 480e dee2 ac1d .8........H..... +// 0x0020: 140f 030d 946e 0000 0000 4520 004d 0000 .....n....E..M.. +// 0x0030: 4000 3e11 2849 ac1d 140f 0a42 49c9 8ecc @.>.(I.....BI... +// 0x0040: 62e1 0039 769d b..9v. +var testICMP = []byte{ + 0x24, 0xbe, 0x05, 0x27, 0x0b, 0x17, 0x00, 0x1f, 0xca, 0xb3, 0x75, 0xc0, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x01, 0xd7, 0xa7, 0x48, 0x0e, 0xde, 0xe2, 0xac, 0x1d, + 0x14, 0x0f, 0x03, 0x0d, 0x94, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x45, 0x20, 0x00, 0x4d, 0x00, 0x00, + 0x40, 0x00, 0x3e, 0x11, 0x28, 0x49, 0xac, 0x1d, 0x14, 0x0f, 0x0a, 0x42, 0x49, 0xc9, 0x8e, 0xcc, + 0x62, 0xe1, 0x00, 0x39, 0x76, 0x9d, +} + +func TestICMP(t *testing.T) { + p := gopacket.NewPacket(testICMP, LinkTypeEthernet, testDecodeOptions) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeICMPv4, gopacket.LayerTypePayload}, t) + testSerialization(t, p, testICMP) +} +func BenchmarkDecodeICMP(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testICMP, LinkTypeEthernet, gopacket.NoCopy) + } +} + +// testICMP6 is the packet: +// 16:17:37.758937 IP6 fe80::21f:caff:feb3:75c0 > 2620:0:1005:0:26be:5ff:fe27:b17: ICMP6, neighbor solicitation, who has 2620:0:1005:0:26be:5ff:fe27:b17, length 32 +// 0x0000: 24be 0527 0b17 001f cab3 75c0 86dd 6e00 $..'......u...n. +// 0x0010: 0000 0020 3aff fe80 0000 0000 0000 021f ....:........... +// 0x0020: caff feb3 75c0 2620 0000 1005 0000 26be ....u.&.......&. +// 0x0030: 05ff fe27 0b17 8700 1eba 0000 0000 2620 ...'..........&. +// 0x0040: 0000 1005 0000 26be 05ff fe27 0b17 0101 ......&....'.... +// 0x0050: 001f cab3 75c0 ....u. +var testICMP6 = []byte{ + 0x24, 0xbe, 0x05, 0x27, 0x0b, 0x17, 0x00, 0x1f, 0xca, 0xb3, 0x75, 0xc0, 0x86, 0xdd, 0x6e, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x3a, 0xff, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1f, + 0xca, 0xff, 0xfe, 0xb3, 0x75, 0xc0, 0x26, 0x20, 0x00, 0x00, 0x10, 0x05, 0x00, 0x00, 0x26, 0xbe, + 0x05, 0xff, 0xfe, 0x27, 0x0b, 0x17, 0x87, 0x00, 0x1e, 0xba, 0x00, 0x00, 0x00, 0x00, 0x26, 0x20, + 0x00, 0x00, 0x10, 0x05, 0x00, 0x00, 0x26, 0xbe, 0x05, 0xff, 0xfe, 0x27, 0x0b, 0x17, 0x01, 0x01, + 0x00, 0x1f, 0xca, 0xb3, 0x75, 0xc0, +} + +func TestICMP6(t *testing.T) { + p := gopacket.NewPacket(testICMP6, LinkTypeEthernet, testDecodeOptions) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv6, LayerTypeICMPv6, gopacket.LayerTypePayload}, t) + testSerialization(t, p, testICMP6) +} +func BenchmarkDecodeICMP6(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testICMP6, LinkTypeEthernet, gopacket.NoCopy) + } +} + +// testMPLS is the packet: +// 12:48:57.201014 MPLS (label 29, exp 0, [S], ttl 255) IP 10.1.2.1 > 10.34.0.1: ICMP echo request, id 2618, seq 1579, length 80 +// 0x0000: 0030 96e6 fc39 0030 9605 2838 8847 0001 .0...9.0..(8.G.. +// 0x0010: d1ff 4500 0064 000b 0000 ff01 a569 0a01 ..E..d.......i.. +// 0x0020: 0201 0a22 0001 0800 3a76 0a3a 062b 0000 ..."....:v.:.+.. +// 0x0030: 0000 001f 3350 abcd abcd abcd abcd abcd ....3P.......... +// 0x0040: abcd abcd abcd abcd abcd abcd abcd abcd ................ +// 0x0050: abcd abcd abcd abcd abcd abcd abcd abcd ................ +// 0x0060: abcd abcd abcd abcd abcd abcd abcd abcd ................ +// 0x0070: abcd abcd abcd ...... +var testMPLS = []byte{ + 0x00, 0x30, 0x96, 0xe6, 0xfc, 0x39, 0x00, 0x30, 0x96, 0x05, 0x28, 0x38, 0x88, 0x47, 0x00, 0x01, + 0xd1, 0xff, 0x45, 0x00, 0x00, 0x64, 0x00, 0x0b, 0x00, 0x00, 0xff, 0x01, 0xa5, 0x69, 0x0a, 0x01, + 0x02, 0x01, 0x0a, 0x22, 0x00, 0x01, 0x08, 0x00, 0x3a, 0x76, 0x0a, 0x3a, 0x06, 0x2b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1f, 0x33, 0x50, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, +} + +func TestMPLS(t *testing.T) { + p := gopacket.NewPacket(testMPLS, LinkTypeEthernet, testDecodeOptions) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeMPLS, LayerTypeIPv4, LayerTypeICMPv4, gopacket.LayerTypePayload}, t) + testSerialization(t, p, testMPLS) +} +func BenchmarkDecodeMPLS(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testMPLS, LinkTypeEthernet, gopacket.NoCopy) + } +} + +// testPPPoEICMPv6 is the packet: +// 07:43:31.091560 PPPoE [ses 0x11] IP6 fe80::c801:eff:fe88:8 > ff02::1: ICMP6, neighbor advertisement, tgt is fe80::c801:eff:fe88:8, length 24 +// 0x0000: cc05 0e88 0000 ca01 0e88 0006 8864 1100 .............d.. +// 0x0010: 0011 0042 0057 6e00 0000 0018 3aff fe80 ...B.Wn.....:... +// 0x0020: 0000 0000 0000 c801 0eff fe88 0008 ff02 ................ +// 0x0030: 0000 0000 0000 0000 0000 0000 0001 8800 ................ +// 0x0040: 5083 8000 0000 fe80 0000 0000 0000 c801 P............... +// 0x0050: 0eff fe88 0008 ...... +var testPPPoEICMPv6 = []byte{ + 0xcc, 0x05, 0x0e, 0x88, 0x00, 0x00, 0xca, 0x01, 0x0e, 0x88, 0x00, 0x06, 0x88, 0x64, 0x11, 0x00, + 0x00, 0x11, 0x00, 0x42, 0x00, 0x57, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3a, 0xff, 0xfe, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x0e, 0xff, 0xfe, 0x88, 0x00, 0x08, 0xff, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x88, 0x00, + 0x50, 0x83, 0x80, 0x00, 0x00, 0x00, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, + 0x0e, 0xff, 0xfe, 0x88, 0x00, 0x08, +} + +func TestPPPoEICMPv6(t *testing.T) { + p := gopacket.NewPacket(testPPPoEICMPv6, LinkTypeEthernet, testDecodeOptions) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{ + LayerTypeEthernet, + LayerTypePPPoE, + LayerTypePPP, + LayerTypeIPv6, + LayerTypeICMPv6, + gopacket.LayerTypePayload, + }, t) + testSerialization(t, p, testPPPoEICMPv6) +} +func BenchmarkDecodePPPoEICMPv6(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPPPoEICMPv6, LinkTypeEthernet, gopacket.NoCopy) + } +} + +var testPFLogUDP = []byte{ + 0x3d, 0x02, 0x00, 0x00, 0x65, 0x6e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xae, 0xff, 0xff, 0xff, 0x7f, + 0xa0, 0x86, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xb8, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x45, 0x00, 0x00, 0x2c, 0x02, 0x16, 0x00, 0x00, 0x40, 0x11, 0x4e, 0xb0, 0xac, 0x17, 0xe8, 0xcc, + 0xac, 0x17, 0xe8, 0xff, 0xf0, 0xff, 0x21, 0xa4, 0x00, 0x18, 0x2a, 0x25, 0x50, 0x4e, 0x4a, 0x50, + 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +} + +func TestPFLogUDP(t *testing.T) { + p := gopacket.NewPacket(testPFLogUDP, LinkTypePFLog, testDecodeOptions) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{ + LayerTypePFLog, + LayerTypeIPv4, + LayerTypeUDP, + gopacket.LayerTypePayload, + }, t) +} + +func TestRegressionDot1QPriority(t *testing.T) { + d := &Dot1Q{ + Priority: 2, + } + out := gopacket.NewSerializeBuffer() + gopacket.SerializeLayers(out, gopacket.SerializeOptions{}, d) + if err := d.DecodeFromBytes(out.Bytes(), gopacket.NilDecodeFeedback); err != nil { + t.Errorf("could not decode encoded dot1q") + } else if d.Priority != 2 { + t.Errorf("priority mismatch, want 2 got %d", d.Priority) + } +} + +// testPacketMPLSInMPLS is the packet: +// 15:27:44.753678 MPLS (label 18, exp 0, ttl 255) (label 16, exp 0, [S], ttl +// 255) IP 10.31.0.1 > 10.34.0.1: ICMP echo request, id 3941, seq 4768, length +// 80 +// 0x0000: 0030 96e6 fc39 0030 9605 2838 8847 0001 .0...9.0..(8.G.. +// 0x0010: 20ff 0001 01ff 4500 0064 0050 0000 ff01 ......E..d.P.... +// 0x0020: a706 0a1f 0001 0a22 0001 0800 bd11 0f65 .......".......e +// 0x0030: 12a0 0000 0000 0053 9ee0 abcd abcd abcd .......S........ +// 0x0040: abcd abcd abcd abcd abcd abcd abcd abcd ................ +// 0x0050: abcd abcd abcd abcd abcd abcd abcd abcd ................ +// 0x0060: abcd abcd abcd abcd abcd abcd abcd abcd ................ +// 0x0070: abcd abcd abcd abcd abcd .......... +var testPacketMPLSInMPLS = []byte{ + 0x00, 0x30, 0x96, 0xe6, 0xfc, 0x39, 0x00, 0x30, 0x96, 0x05, 0x28, 0x38, 0x88, 0x47, 0x00, 0x01, + 0x20, 0xff, 0x00, 0x01, 0x01, 0xff, 0x45, 0x00, 0x00, 0x64, 0x00, 0x50, 0x00, 0x00, 0xff, 0x01, + 0xa7, 0x06, 0x0a, 0x1f, 0x00, 0x01, 0x0a, 0x22, 0x00, 0x01, 0x08, 0x00, 0xbd, 0x11, 0x0f, 0x65, + 0x12, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x9e, 0xe0, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, +} + +func TestPacketMPLSInMPLS(t *testing.T) { + p := gopacket.NewPacket(testPacketMPLSInMPLS, LinkTypeEthernet, testDecodeOptions) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{ + LayerTypeEthernet, + LayerTypeMPLS, + LayerTypeMPLS, + LayerTypeIPv4, + LayerTypeICMPv4, + gopacket.LayerTypePayload}, t) +} + +// testPacketIPv4Fragmented is the packet: +// 22:11:26.616090 IP 10.1.1.1.31915 > 129.111.30.27.20197: UDP, length 28 +// 0x0000: 0000 39cf d9cd 0040 33d9 7cfd 0800 4500 ..9....@3.|...E. +// 0x0010: 0038 00f2 2000 4011 af37 0a01 0101 816f .8....@..7.....o +// 0x0020: 1e1b 7cab 4ee5 0024 0000 0000 0000 0000 ..|.N..$........ +// 0x0030: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +// 0x0040: 0000 0000 0000 ...... +var testPacketIPv4Fragmented = []byte{ + 0x00, 0x00, 0x39, 0xcf, 0xd9, 0xcd, 0x00, 0x40, 0x33, 0xd9, 0x7c, 0xfd, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x38, 0x00, 0xf2, 0x20, 0x00, 0x40, 0x11, 0xaf, 0x37, 0x0a, 0x01, 0x01, 0x01, 0x81, 0x6f, + 0x1e, 0x1b, 0x7c, 0xab, 0x4e, 0xe5, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +} + +func TestPacketIPv4Fragmented(t *testing.T) { + p := gopacket.NewPacket(testPacketIPv4Fragmented, LinkTypeEthernet, testDecodeOptions) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, gopacket.LayerTypeFragment}, t) + testSerializationWithOpts(t, p, testPacketIPv4Fragmented, gopacket.SerializeOptions{FixLengths: true, ComputeChecksums: true}) +} + +// TestSCTPChunkBadLength tests for issue #146 +func TestSCTPChunkBadLength(t *testing.T) { + data := []byte( + "0000\xad9$e\x11\xe4\xaeo\b\x00E\x00\x018\xb4\xa3" + + "\x00\x00Y\x84\xc4@\x11gz\xc0\xa8\xee\x01\xc0\xa8" + + "\xeeD\x007le\x03\x01\xc0\f\xdf\b\x01\x00\x00") + + // this panic'd previously due to a zero length chunk getting + // repeatedly read + gopacket.NewPacket(data, LinkTypeEthernet, gopacket.Default) +} + +// TestSTP +func TestSTP(t *testing.T) { + testSTPpacket := []byte{ + 0x01, 0x80, 0xC2, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x0E, 0x87, 0x85, 0x04, 0x00, 0x26, 0x42, 0x42, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x64, 0x00, 0x1C, 0x0E, 0x87, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x80, 0x64, 0x00, 0x1C, 0x0E, 0x87, 0x85, 0x00, 0x80, 0x04, 0x01, 0x00, 0x14, 0x00, + 0x02, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + } + p := gopacket.NewPacket(testSTPpacket, LinkTypeEthernet, testDecodeOptions) + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeLLC, LayerTypeSTP}, t) +} diff --git a/vendor/github.com/google/gopacket/layers/dhcp_test.go b/vendor/github.com/google/gopacket/layers/dhcp_test.go new file mode 100644 index 0000000..c4975dc --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/dhcp_test.go @@ -0,0 +1,129 @@ +// Copyright 2016, Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "bytes" + "net" + "testing" + + "github.com/google/gopacket" +) + +func TestDHCPv4EncodeRequest(t *testing.T) { + dhcp := &DHCPv4{Operation: DHCPOpRequest, HardwareType: LinkTypeEthernet, Xid: 0x12345678, + ClientIP: net.IP{0, 0, 0, 0}, YourClientIP: net.IP{0, 0, 0, 0}, NextServerIP: net.IP{0, 0, 0, 0}, RelayAgentIP: net.IP{0, 0, 0, 0}, + ClientHWAddr: net.HardwareAddr{0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc}, + ServerName: make([]byte, 64), File: make([]byte, 128)} + + dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptMessageType, []byte{byte(DHCPMsgTypeDiscover)})) + dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptHostname, []byte{'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm'})) + dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptPad, nil)) + dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptParamsRequest, + []byte{byte(DHCPOptSubnetMask), byte(DHCPOptBroadcastAddr), byte(DHCPOptTimeOffset), + byte(DHCPOptRouter), byte(DHCPOptDomainName), byte(DHCPOptDNS), byte(DHCPOptDomainSearch), + byte(DHCPOptHostname), byte(DHCPOptNetBIOSTCPNS), byte(DHCPOptInterfaceMTU), byte(DHCPOptClasslessStaticRoute), + byte(DHCPOptNTPServers)})) + + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{FixLengths: true} + err := gopacket.SerializeLayers(buf, opts, dhcp) + if err != nil { + t.Fatal(err) + } + + p2 := gopacket.NewPacket(buf.Bytes(), LayerTypeDHCPv4, testDecodeOptions) + dhcp2 := p2.Layer(LayerTypeDHCPv4).(*DHCPv4) + testDHCPEqual(t, dhcp, dhcp2) +} + +func TestDHCPv4EncodeResponse(t *testing.T) { + dhcp := &DHCPv4{Operation: DHCPOpReply, HardwareType: LinkTypeEthernet, Xid: 0x12345678, + ClientIP: net.IP{0, 0, 0, 0}, YourClientIP: net.IP{192, 168, 0, 123}, NextServerIP: net.IP{192, 168, 0, 1}, RelayAgentIP: net.IP{0, 0, 0, 0}, + ClientHWAddr: net.HardwareAddr{0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc}, + ServerName: make([]byte, 64), File: make([]byte, 128)} + + dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptMessageType, []byte{byte(DHCPMsgTypeOffer)})) + dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptSubnetMask, []byte{255, 255, 255, 0})) + dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptPad, nil)) + dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptT1, []byte{0x00, 0x00, 0x0e, 0x10})) + dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptT2, []byte{0x00, 0x00, 0x0e, 0x10})) + dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptLeaseTime, []byte{0x00, 0x00, 0x0e, 0x10})) + dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptServerID, []byte{192, 168, 0, 1})) + + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{FixLengths: true} + err := gopacket.SerializeLayers(buf, opts, dhcp) + if err != nil { + t.Fatal(err) + } + + p2 := gopacket.NewPacket(buf.Bytes(), LayerTypeDHCPv4, testDecodeOptions) + dhcp2 := p2.Layer(LayerTypeDHCPv4).(*DHCPv4) + testDHCPEqual(t, dhcp, dhcp2) +} + +func testDHCPEqual(t *testing.T, d1, d2 *DHCPv4) { + if d1.Operation != d2.Operation { + t.Errorf("expected Operation=%s, got %s", d1.Operation, d2.Operation) + } + if d1.HardwareType != d2.HardwareType { + t.Errorf("expected HardwareType=%s, got %s", d1.HardwareType, d2.HardwareType) + } + if d1.HardwareLen != d2.HardwareLen { + t.Errorf("expected HardwareLen=%v, got %v", d1.HardwareLen, d2.HardwareLen) + } + if d1.HardwareOpts != d2.HardwareOpts { + t.Errorf("expected HardwareOpts=%v, got %v", d1.HardwareOpts, d2.HardwareOpts) + } + if d1.Xid != d2.Xid { + t.Errorf("expected Xid=%v, got %v", d1.Xid, d2.Xid) + } + if d1.Secs != d2.Secs { + t.Errorf("expected Secs=%v, got %v", d1.Secs, d2.Secs) + } + if d1.Flags != d2.Flags { + t.Errorf("expected Flags=%v, got %v", d1.Flags, d2.Flags) + } + if !d1.ClientIP.Equal(d2.ClientIP) { + t.Errorf("expected ClientIP=%v, got %v", d1.ClientIP, d2.ClientIP) + } + if !d1.YourClientIP.Equal(d2.YourClientIP) { + t.Errorf("expected YourClientIP=%v, got %v", d1.YourClientIP, d2.YourClientIP) + } + if !d1.NextServerIP.Equal(d2.NextServerIP) { + t.Errorf("expected NextServerIP=%v, got %v", d1.NextServerIP, d2.NextServerIP) + } + if !d1.RelayAgentIP.Equal(d2.RelayAgentIP) { + t.Errorf("expected RelayAgentIP=%v, got %v", d1.RelayAgentIP, d2.RelayAgentIP) + } + if !bytes.Equal(d1.ClientHWAddr, d2.ClientHWAddr) { + t.Errorf("expected ClientHWAddr=%v, got %v", d1.ClientHWAddr, d2.ClientHWAddr) + } + if !bytes.Equal(d1.ServerName, d2.ServerName) { + t.Errorf("expected ServerName=%v, got %v", d1.ServerName, d2.ServerName) + } + if !bytes.Equal(d1.File, d2.File) { + t.Errorf("expected File=%v, got %v", d1.File, d2.File) + } + if len(d1.Options) != len(d2.Options) { + t.Errorf("expected %d options, got %d", len(d1.Options), len(d2.Options)) + } + + for i, o := range d1.Options { + testDHCPOptionEqual(t, i, o, d2.Options[i]) + } +} + +func testDHCPOptionEqual(t *testing.T, idx int, d1, d2 DHCPOption) { + if d1.Type != d2.Type { + t.Errorf("expection Options[%d].Type = %s, got %s", idx, d1.Type, d2.Type) + } + if !bytes.Equal(d1.Data, d2.Data) { + t.Errorf("expection Options[%d].Data to be = %v, got %v", idx, d1.Data, d2.Data) + } +} diff --git a/vendor/github.com/google/gopacket/layers/dhcpv4.go b/vendor/github.com/google/gopacket/layers/dhcpv4.go new file mode 100644 index 0000000..761b201 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/dhcpv4.go @@ -0,0 +1,571 @@ +// Copyright 2016 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "bytes" + "encoding/binary" + "errors" + "fmt" + "net" + + "github.com/google/gopacket" +) + +// DHCPOp rerprents a bootp operation +type DHCPOp byte + +// bootp operations +const ( + DHCPOpRequest DHCPOp = 1 + DHCPOpReply DHCPOp = 2 +) + +// String returns a string version of a DHCPOp. +func (o DHCPOp) String() string { + switch o { + case DHCPOpRequest: + return "Request" + case DHCPOpReply: + return "Reply" + default: + return "Unknown" + } +} + +// DHCPMsgType represents a DHCP operation +type DHCPMsgType byte + +// Constants that represent DHCP operations +const ( + DHCPMsgTypeUnspecified DHCPMsgType = iota + DHCPMsgTypeDiscover + DHCPMsgTypeOffer + DHCPMsgTypeRequest + DHCPMsgTypeDecline + DHCPMsgTypeAck + DHCPMsgTypeNak + DHCPMsgTypeRelease + DHCPMsgTypeInform +) + +// String returns a string version of a DHCPMsgType. +func (o DHCPMsgType) String() string { + switch o { + case DHCPMsgTypeUnspecified: + return "Unspecified" + case DHCPMsgTypeDiscover: + return "Discover" + case DHCPMsgTypeOffer: + return "Offer" + case DHCPMsgTypeRequest: + return "Request" + case DHCPMsgTypeDecline: + return "Decline" + case DHCPMsgTypeAck: + return "Ack" + case DHCPMsgTypeNak: + return "Nak" + case DHCPMsgTypeRelease: + return "Release" + case DHCPMsgTypeInform: + return "Inform" + default: + return "Unknown" + } +} + +//DHCPMagic is the RFC 2131 "magic cooke" for DHCP. +var DHCPMagic uint32 = 0x63825363 + +// DHCPv4 contains data for a single DHCP packet. +type DHCPv4 struct { + BaseLayer + Operation DHCPOp + HardwareType LinkType + HardwareLen uint8 + HardwareOpts uint8 + Xid uint32 + Secs uint16 + Flags uint16 + ClientIP net.IP + YourClientIP net.IP + NextServerIP net.IP + RelayAgentIP net.IP + ClientHWAddr net.HardwareAddr + ServerName []byte + File []byte + Options DHCPOptions +} + +// DHCPOptions is used to get nicely printed option lists which would normally +// be cut off after 5 options. +type DHCPOptions []DHCPOption + +// String returns a string version of the options list. +func (o DHCPOptions) String() string { + buf := &bytes.Buffer{} + buf.WriteByte('[') + for i, opt := range o { + buf.WriteString(opt.String()) + if i+1 != len(o) { + buf.WriteString(", ") + } + } + buf.WriteByte(']') + return buf.String() +} + +// LayerType returns gopacket.LayerTypeDHCPv4 +func (d *DHCPv4) LayerType() gopacket.LayerType { return LayerTypeDHCPv4 } + +// DecodeFromBytes decodes the given bytes into this layer. +func (d *DHCPv4) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + d.Operation = DHCPOp(data[0]) + d.HardwareType = LinkType(data[1]) + d.HardwareLen = data[2] + d.HardwareOpts = data[3] + d.Xid = binary.BigEndian.Uint32(data[4:8]) + d.Secs = binary.BigEndian.Uint16(data[8:10]) + d.Flags = binary.BigEndian.Uint16(data[10:12]) + d.ClientIP = net.IP(data[12:16]) + d.YourClientIP = net.IP(data[16:20]) + d.NextServerIP = net.IP(data[20:24]) + d.RelayAgentIP = net.IP(data[24:28]) + d.ClientHWAddr = net.HardwareAddr(data[28 : 28+d.HardwareLen]) + d.ServerName = data[44:108] + d.File = data[108:236] + if binary.BigEndian.Uint32(data[236:240]) != DHCPMagic { + return errors.New("Bad DHCP header") + } + + if len(data) <= 240 { + // DHCP Packet could have no option (??) + return nil + } + + options := data[240:] + + stop := len(options) + start := 0 + for start < stop { + o := DHCPOption{} + if err := o.decode(options[start:]); err != nil { + return err + } + if o.Type == DHCPOptEnd { + break + } + d.Options = append(d.Options, o) + // Check if the option is a single byte pad + if o.Type == DHCPOptPad { + start++ + } else { + start += int(o.Length) + 2 + } + } + return nil +} + +// Len returns the length of a DHCPv4 packet. +func (d *DHCPv4) Len() uint16 { + n := uint16(240) + for _, o := range d.Options { + if o.Type == DHCPOptPad { + n++ + } else { + n += uint16(o.Length) + 2 + } + } + n++ // for opt end + return n +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (d *DHCPv4) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + plen := int(d.Len()) + + data, err := b.PrependBytes(plen) + if err != nil { + return err + } + + data[0] = byte(d.Operation) + data[1] = byte(d.HardwareType) + if opts.FixLengths { + d.HardwareLen = uint8(len(d.ClientHWAddr)) + } + data[2] = d.HardwareLen + data[3] = d.HardwareOpts + binary.BigEndian.PutUint32(data[4:8], d.Xid) + binary.BigEndian.PutUint16(data[8:10], d.Secs) + binary.BigEndian.PutUint16(data[10:12], d.Flags) + copy(data[12:16], d.ClientIP.To4()) + copy(data[16:20], d.YourClientIP.To4()) + copy(data[20:24], d.NextServerIP.To4()) + copy(data[24:28], d.RelayAgentIP.To4()) + copy(data[28:44], d.ClientHWAddr) + copy(data[44:108], d.ServerName) + copy(data[108:236], d.File) + binary.BigEndian.PutUint32(data[236:240], DHCPMagic) + + if len(d.Options) > 0 { + offset := 240 + for _, o := range d.Options { + if err := o.encode(data[offset:]); err != nil { + return err + } + // A pad option is only a single byte + if o.Type == DHCPOptPad { + offset++ + } else { + offset += 2 + len(o.Data) + } + } + optend := NewDHCPOption(DHCPOptEnd, nil) + if err := optend.encode(data[offset:]); err != nil { + return err + } + } + return nil +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (d *DHCPv4) CanDecode() gopacket.LayerClass { + return LayerTypeDHCPv4 +} + +// NextLayerType returns the layer type contained by this DecodingLayer. +func (d *DHCPv4) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypePayload +} + +func decodeDHCPv4(data []byte, p gopacket.PacketBuilder) error { + dhcp := &DHCPv4{} + err := dhcp.DecodeFromBytes(data, p) + if err != nil { + return err + } + p.AddLayer(dhcp) + return p.NextDecoder(gopacket.LayerTypePayload) +} + +// DHCPOpt represents a DHCP option or parameter from RFC-2132 +type DHCPOpt byte + +// Constants for the DHCPOpt options. +const ( + DHCPOptPad DHCPOpt = 0 + DHCPOptSubnetMask DHCPOpt = 1 // 4, net.IP + DHCPOptTimeOffset DHCPOpt = 2 // 4, int32 (signed seconds from UTC) + DHCPOptRouter DHCPOpt = 3 // n*4, [n]net.IP + DHCPOptTimeServer DHCPOpt = 4 // n*4, [n]net.IP + DHCPOptNameServer DHCPOpt = 5 // n*4, [n]net.IP + DHCPOptDNS DHCPOpt = 6 // n*4, [n]net.IP + DHCPOptLogServer DHCPOpt = 7 // n*4, [n]net.IP + DHCPOptCookieServer DHCPOpt = 8 // n*4, [n]net.IP + DHCPOptLPRServer DHCPOpt = 9 // n*4, [n]net.IP + DHCPOptImpressServer DHCPOpt = 10 // n*4, [n]net.IP + DHCPOptResLocServer DHCPOpt = 11 // n*4, [n]net.IP + DHCPOptHostname DHCPOpt = 12 // n, string + DHCPOptBootfileSize DHCPOpt = 13 // 2, uint16 + DHCPOptMeritDumpFile DHCPOpt = 14 // >1, string + DHCPOptDomainName DHCPOpt = 15 // n, string + DHCPOptSwapServer DHCPOpt = 16 // n*4, [n]net.IP + DHCPOptRootPath DHCPOpt = 17 // n, string + DHCPOptExtensionsPath DHCPOpt = 18 // n, string + DHCPOptIPForwarding DHCPOpt = 19 // 1, bool + DHCPOptSourceRouting DHCPOpt = 20 // 1, bool + DHCPOptPolicyFilter DHCPOpt = 21 // 8*n, [n]{net.IP/net.IP} + DHCPOptDatagramMTU DHCPOpt = 22 // 2, uint16 + DHCPOptDefaultTTL DHCPOpt = 23 // 1, byte + DHCPOptPathMTUAgingTimeout DHCPOpt = 24 // 4, uint32 + DHCPOptPathPlateuTableOption DHCPOpt = 25 // 2*n, []uint16 + DHCPOptInterfaceMTU DHCPOpt = 26 // 2, uint16 + DHCPOptAllSubsLocal DHCPOpt = 27 // 1, bool + DHCPOptBroadcastAddr DHCPOpt = 28 // 4, net.IP + DHCPOptMaskDiscovery DHCPOpt = 29 // 1, bool + DHCPOptMaskSupplier DHCPOpt = 30 // 1, bool + DHCPOptRouterDiscovery DHCPOpt = 31 // 1, bool + DHCPOptSolicitAddr DHCPOpt = 32 // 4, net.IP + DHCPOptStaticRoute DHCPOpt = 33 // n*8, [n]{net.IP/net.IP} -- note the 2nd is router not mask + DHCPOptARPTrailers DHCPOpt = 34 // 1, bool + DHCPOptARPTimeout DHCPOpt = 35 // 4, uint32 + DHCPOptEthernetEncap DHCPOpt = 36 // 1, bool + DHCPOptTCPTTL DHCPOpt = 37 // 1, byte + DHCPOptTCPKeepAliveInt DHCPOpt = 38 // 4, uint32 + DHCPOptTCPKeepAliveGarbage DHCPOpt = 39 // 1, bool + DHCPOptNISDomain DHCPOpt = 40 // n, string + DHCPOptNISServers DHCPOpt = 41 // 4*n, [n]net.IP + DHCPOptNTPServers DHCPOpt = 42 // 4*n, [n]net.IP + DHCPOptVendorOption DHCPOpt = 43 // n, [n]byte // may be encapsulated. + DHCPOptNetBIOSTCPNS DHCPOpt = 44 // 4*n, [n]net.IP + DHCPOptNetBIOSTCPDDS DHCPOpt = 45 // 4*n, [n]net.IP + DHCPOptNETBIOSTCPNodeType DHCPOpt = 46 // 1, magic byte + DHCPOptNetBIOSTCPScope DHCPOpt = 47 // n, string + DHCPOptXFontServer DHCPOpt = 48 // n, string + DHCPOptXDisplayManager DHCPOpt = 49 // n, string + DHCPOptRequestIP DHCPOpt = 50 // 4, net.IP + DHCPOptLeaseTime DHCPOpt = 51 // 4, uint32 + DHCPOptExtOptions DHCPOpt = 52 // 1, 1/2/3 + DHCPOptMessageType DHCPOpt = 53 // 1, 1-7 + DHCPOptServerID DHCPOpt = 54 // 4, net.IP + DHCPOptParamsRequest DHCPOpt = 55 // n, []byte + DHCPOptMessage DHCPOpt = 56 // n, 3 + DHCPOptMaxMessageSize DHCPOpt = 57 // 2, uint16 + DHCPOptT1 DHCPOpt = 58 // 4, uint32 + DHCPOptT2 DHCPOpt = 59 // 4, uint32 + DHCPOptClassID DHCPOpt = 60 // n, []byte + DHCPOptClientID DHCPOpt = 61 // n >= 2, []byte + DHCPOptDomainSearch DHCPOpt = 119 // n, string + DHCPOptSIPServers DHCPOpt = 120 // n, url + DHCPOptClasslessStaticRoute DHCPOpt = 121 // + DHCPOptEnd DHCPOpt = 255 +) + +// String returns a string version of a DHCPOpt. +func (o DHCPOpt) String() string { + switch o { + case DHCPOptPad: + return "(padding)" + case DHCPOptSubnetMask: + return "SubnetMask" + case DHCPOptTimeOffset: + return "TimeOffset" + case DHCPOptRouter: + return "Router" + case DHCPOptTimeServer: + return "rfc868" // old time server protocol stringified to dissuade confusion w. NTP + case DHCPOptNameServer: + return "ien116" // obscure nameserver protocol stringified to dissuade confusion w. DNS + case DHCPOptDNS: + return "DNS" + case DHCPOptLogServer: + return "mitLCS" // MIT LCS server protocol yada yada w. Syslog + case DHCPOptCookieServer: + return "CookieServer" + case DHCPOptLPRServer: + return "LPRServer" + case DHCPOptImpressServer: + return "ImpressServer" + case DHCPOptResLocServer: + return "ResourceLocationServer" + case DHCPOptHostname: + return "Hostname" + case DHCPOptBootfileSize: + return "BootfileSize" + case DHCPOptMeritDumpFile: + return "MeritDumpFile" + case DHCPOptDomainName: + return "DomainName" + case DHCPOptSwapServer: + return "SwapServer" + case DHCPOptRootPath: + return "RootPath" + case DHCPOptExtensionsPath: + return "ExtensionsPath" + case DHCPOptIPForwarding: + return "IPForwarding" + case DHCPOptSourceRouting: + return "SourceRouting" + case DHCPOptPolicyFilter: + return "PolicyFilter" + case DHCPOptDatagramMTU: + return "DatagramMTU" + case DHCPOptDefaultTTL: + return "DefaultTTL" + case DHCPOptPathMTUAgingTimeout: + return "PathMTUAgingTimeout" + case DHCPOptPathPlateuTableOption: + return "PathPlateuTableOption" + case DHCPOptInterfaceMTU: + return "InterfaceMTU" + case DHCPOptAllSubsLocal: + return "AllSubsLocal" + case DHCPOptBroadcastAddr: + return "BroadcastAddress" + case DHCPOptMaskDiscovery: + return "MaskDiscovery" + case DHCPOptMaskSupplier: + return "MaskSupplier" + case DHCPOptRouterDiscovery: + return "RouterDiscovery" + case DHCPOptSolicitAddr: + return "SolicitAddr" + case DHCPOptStaticRoute: + return "StaticRoute" + case DHCPOptARPTrailers: + return "ARPTrailers" + case DHCPOptARPTimeout: + return "ARPTimeout" + case DHCPOptEthernetEncap: + return "EthernetEncap" + case DHCPOptTCPTTL: + return "TCPTTL" + case DHCPOptTCPKeepAliveInt: + return "TCPKeepAliveInt" + case DHCPOptTCPKeepAliveGarbage: + return "TCPKeepAliveGarbage" + case DHCPOptNISDomain: + return "NISDomain" + case DHCPOptNISServers: + return "NISServers" + case DHCPOptNTPServers: + return "NTPServers" + case DHCPOptVendorOption: + return "VendorOption" + case DHCPOptNetBIOSTCPNS: + return "NetBIOSOverTCPNS" + case DHCPOptNetBIOSTCPDDS: + return "NetBiosOverTCPDDS" + case DHCPOptNETBIOSTCPNodeType: + return "NetBIOSOverTCPNodeType" + case DHCPOptNetBIOSTCPScope: + return "NetBIOSOverTCPScope" + case DHCPOptXFontServer: + return "XFontServer" + case DHCPOptXDisplayManager: + return "XDisplayManager" + case DHCPOptEnd: + return "(end)" + case DHCPOptSIPServers: + return "SipServers" + case DHCPOptRequestIP: + return "RequestIP" + case DHCPOptLeaseTime: + return "LeaseTime" + case DHCPOptExtOptions: + return "ExtOpts" + case DHCPOptMessageType: + return "MessageType" + case DHCPOptServerID: + return "ServerID" + case DHCPOptParamsRequest: + return "ParamsRequest" + case DHCPOptMessage: + return "Message" + case DHCPOptMaxMessageSize: + return "MaxDHCPSize" + case DHCPOptT1: + return "Timer1" + case DHCPOptT2: + return "Timer2" + case DHCPOptClassID: + return "ClassID" + case DHCPOptClientID: + return "ClientID" + case DHCPOptDomainSearch: + return "DomainSearch" + case DHCPOptClasslessStaticRoute: + return "ClasslessStaticRoute" + default: + return "Unknown" + } +} + +// DHCPOption rerpresents a DHCP option. +type DHCPOption struct { + Type DHCPOpt + Length uint8 + Data []byte +} + +// String returns a string version of a DHCP Option. +func (o DHCPOption) String() string { + switch o.Type { + + case DHCPOptHostname, DHCPOptMeritDumpFile, DHCPOptDomainName, DHCPOptRootPath, + DHCPOptExtensionsPath, DHCPOptNISDomain, DHCPOptNetBIOSTCPScope, DHCPOptXFontServer, + DHCPOptXDisplayManager, DHCPOptMessage, DHCPOptDomainSearch: // string + return fmt.Sprintf("Option(%s:%s)", o.Type, string(o.Data)) + + case DHCPOptMessageType: + if len(o.Data) != 1 { + return fmt.Sprintf("Option(%s:INVALID)", o.Type) + } + return fmt.Sprintf("Option(%s:%s)", o.Type, DHCPMsgType(o.Data[0])) + + case DHCPOptSubnetMask, DHCPOptServerID, DHCPOptBroadcastAddr, + DHCPOptSolicitAddr, DHCPOptRequestIP: // net.IP + if len(o.Data) < 4 { + return fmt.Sprintf("Option(%s:INVALID)", o.Type) + } + return fmt.Sprintf("Option(%s:%s)", o.Type, net.IP(o.Data)) + + case DHCPOptT1, DHCPOptT2, DHCPOptLeaseTime, DHCPOptPathMTUAgingTimeout, + DHCPOptARPTimeout, DHCPOptTCPKeepAliveInt: // uint32 + if len(o.Data) != 4 { + return fmt.Sprintf("Option(%s:INVALID)", o.Type) + } + return fmt.Sprintf("Option(%s:%d)", o.Type, + uint32(o.Data[0])<<24|uint32(o.Data[1])<<16|uint32(o.Data[2])<<8|uint32(o.Data[3])) + + case DHCPOptParamsRequest: + buf := &bytes.Buffer{} + buf.WriteString(fmt.Sprintf("Option(%s:", o.Type)) + for i, v := range o.Data { + buf.WriteString(DHCPOpt(v).String()) + if i+1 != len(o.Data) { + buf.WriteByte(',') + } + } + buf.WriteString(")") + return buf.String() + + default: + return fmt.Sprintf("Option(%s:%v)", o.Type, o.Data) + } +} + +// NewDHCPOption constructs a new DHCPOption with a given type and data. +func NewDHCPOption(t DHCPOpt, data []byte) DHCPOption { + o := DHCPOption{Type: t} + if data != nil { + o.Data = data + o.Length = uint8(len(data)) + } + return o +} + +func (o *DHCPOption) encode(b []byte) error { + switch o.Type { + case DHCPOptPad, DHCPOptEnd: + b[0] = byte(o.Type) + default: + if o.Length > 253 { + return errors.New("data too long to encode") + } + b[0] = byte(o.Type) + b[1] = o.Length + copy(b[2:], o.Data) + } + return nil +} + +func (o *DHCPOption) decode(data []byte) error { + if len(data) < 1 { + // Pad/End have a length of 1 + return errors.New("Not enough data to decode") + } + o.Type = DHCPOpt(data[0]) + switch o.Type { + case DHCPOptPad, DHCPOptEnd: + o.Data = nil + default: + if len(data) < 3 { + return errors.New("Not enough data to decode") + } + o.Length = data[1] + if o.Length > 253 { + return errors.New("data too long to decode") + } + o.Data = data[2 : 2+o.Length] + } + return nil +} diff --git a/vendor/github.com/google/gopacket/layers/dns.go b/vendor/github.com/google/gopacket/layers/dns.go new file mode 100644 index 0000000..2368a28 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/dns.go @@ -0,0 +1,894 @@ +// Copyright 2014 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "errors" + "fmt" + "net" + + "github.com/google/gopacket" +) + +// DNSClass defines the class associated with a request/response. Different DNS +// classes can be thought of as an array of parallel namespace trees. +type DNSClass uint16 + +// DNSClass known values. +const ( + DNSClassIN DNSClass = 1 // Internet + DNSClassCS DNSClass = 2 // the CSNET class (Obsolete) + DNSClassCH DNSClass = 3 // the CHAOS class + DNSClassHS DNSClass = 4 // Hesiod [Dyer 87] + DNSClassAny DNSClass = 255 // AnyClass +) + +func (dc DNSClass) String() string { + switch dc { + default: + return "Unknown" + case DNSClassIN: + return "IN" + case DNSClassCS: + return "CS" + case DNSClassCH: + return "CH" + case DNSClassHS: + return "HS" + case DNSClassAny: + return "Any" + } +} + +// DNSType defines the type of data being requested/returned in a +// question/answer. +type DNSType uint16 + +// DNSType known values. +const ( + DNSTypeA DNSType = 1 // a host address + DNSTypeNS DNSType = 2 // an authoritative name server + DNSTypeMD DNSType = 3 // a mail destination (Obsolete - use MX) + DNSTypeMF DNSType = 4 // a mail forwarder (Obsolete - use MX) + DNSTypeCNAME DNSType = 5 // the canonical name for an alias + DNSTypeSOA DNSType = 6 // marks the start of a zone of authority + DNSTypeMB DNSType = 7 // a mailbox domain name (EXPERIMENTAL) + DNSTypeMG DNSType = 8 // a mail group member (EXPERIMENTAL) + DNSTypeMR DNSType = 9 // a mail rename domain name (EXPERIMENTAL) + DNSTypeNULL DNSType = 10 // a null RR (EXPERIMENTAL) + DNSTypeWKS DNSType = 11 // a well known service description + DNSTypePTR DNSType = 12 // a domain name pointer + DNSTypeHINFO DNSType = 13 // host information + DNSTypeMINFO DNSType = 14 // mailbox or mail list information + DNSTypeMX DNSType = 15 // mail exchange + DNSTypeTXT DNSType = 16 // text strings + DNSTypeAAAA DNSType = 28 // a IPv6 host address [RFC3596] + DNSTypeSRV DNSType = 33 // server discovery [RFC2782] [RFC6195] +) + +func (dt DNSType) String() string { + switch dt { + default: + return "Unknown" + case DNSTypeA: + return "A" + case DNSTypeNS: + return "NS" + case DNSTypeMD: + return "MD" + case DNSTypeMF: + return "MF" + case DNSTypeCNAME: + return "CNAME" + case DNSTypeSOA: + return "SOA" + case DNSTypeMB: + return "MB" + case DNSTypeMG: + return "MG" + case DNSTypeMR: + return "MR" + case DNSTypeNULL: + return "NULL" + case DNSTypeWKS: + return "WKS" + case DNSTypePTR: + return "PTR" + case DNSTypeHINFO: + return "HINFO" + case DNSTypeMINFO: + return "MINFO" + case DNSTypeMX: + return "MX" + case DNSTypeTXT: + return "TXT" + case DNSTypeAAAA: + return "AAAA" + case DNSTypeSRV: + return "SRV" + } +} + +// DNSResponseCode provides response codes for question answers. +type DNSResponseCode uint8 + +// DNSResponseCode known values. +const ( + DNSResponseCodeNoErr DNSResponseCode = 0 // No error + DNSResponseCodeFormErr DNSResponseCode = 1 // Format Error [RFC1035] + DNSResponseCodeServFail DNSResponseCode = 2 // Server Failure [RFC1035] + DNSResponseCodeNXDomain DNSResponseCode = 3 // Non-Existent Domain [RFC1035] + DNSResponseCodeNotImp DNSResponseCode = 4 // Not Implemented [RFC1035] + DNSResponseCodeRefused DNSResponseCode = 5 // Query Refused [RFC1035] + DNSResponseCodeYXDomain DNSResponseCode = 6 // Name Exists when it should not [RFC2136] + DNSResponseCodeYXRRSet DNSResponseCode = 7 // RR Set Exists when it should not [RFC2136] + DNSResponseCodeNXRRSet DNSResponseCode = 8 // RR Set that should exist does not [RFC2136] + DNSResponseCodeNotAuth DNSResponseCode = 9 // Server Not Authoritative for zone [RFC2136] + DNSResponseCodeNotZone DNSResponseCode = 10 // Name not contained in zone [RFC2136] + DNSResponseCodeBadVers DNSResponseCode = 16 // Bad OPT Version [RFC2671] + DNSResponseCodeBadSig DNSResponseCode = 16 // TSIG Signature Failure [RFC2845] + DNSResponseCodeBadKey DNSResponseCode = 17 // Key not recognized [RFC2845] + DNSResponseCodeBadTime DNSResponseCode = 18 // Signature out of time window [RFC2845] + DNSResponseCodeBadMode DNSResponseCode = 19 // Bad TKEY Mode [RFC2930] + DNSResponseCodeBadName DNSResponseCode = 20 // Duplicate key name [RFC2930] + DNSResponseCodeBadAlg DNSResponseCode = 21 // Algorithm not supported [RFC2930] + DNSResponseCodeBadTruc DNSResponseCode = 22 // Bad Truncation [RFC4635] +) + +func (drc DNSResponseCode) String() string { + switch drc { + default: + return "Unknown" + case DNSResponseCodeNoErr: + return "No Error" + case DNSResponseCodeFormErr: + return "Format Error" + case DNSResponseCodeServFail: + return "Server Failure " + case DNSResponseCodeNXDomain: + return "Non-Existent Domain" + case DNSResponseCodeNotImp: + return "Not Implemented" + case DNSResponseCodeRefused: + return "Query Refused" + case DNSResponseCodeYXDomain: + return "Name Exists when it should not" + case DNSResponseCodeYXRRSet: + return "RR Set Exists when it should not" + case DNSResponseCodeNXRRSet: + return "RR Set that should exist does not" + case DNSResponseCodeNotAuth: + return "Server Not Authoritative for zone" + case DNSResponseCodeNotZone: + return "Name not contained in zone" + case DNSResponseCodeBadVers: + return "Bad OPT Version" + case DNSResponseCodeBadKey: + return "Key not recognized" + case DNSResponseCodeBadTime: + return "Signature out of time window" + case DNSResponseCodeBadMode: + return "Bad TKEY Mode" + case DNSResponseCodeBadName: + return "Duplicate key name" + case DNSResponseCodeBadAlg: + return "Algorithm not supported" + case DNSResponseCodeBadTruc: + return "Bad Truncation" + } +} + +// DNSOpCode defines a set of different operation types. +type DNSOpCode uint8 + +// DNSOpCode known values. +const ( + DNSOpCodeQuery DNSOpCode = 0 // Query [RFC1035] + DNSOpCodeIQuery DNSOpCode = 1 // Inverse Query Obsolete [RFC3425] + DNSOpCodeStatus DNSOpCode = 2 // Status [RFC1035] + DNSOpCodeNotify DNSOpCode = 4 // Notify [RFC1996] + DNSOpCodeUpdate DNSOpCode = 5 // Update [RFC2136] +) + +func (doc DNSOpCode) String() string { + switch doc { + default: + return "Unknown" + case DNSOpCodeQuery: + return "Query" + case DNSOpCodeIQuery: + return "Inverse Query" + case DNSOpCodeStatus: + return "Status" + case DNSOpCodeNotify: + return "Notify" + case DNSOpCodeUpdate: + return "Update" + } +} + +// DNS is specified in RFC 1034 / RFC 1035 +// +---------------------+ +// | Header | +// +---------------------+ +// | Question | the question for the name server +// +---------------------+ +// | Answer | RRs answering the question +// +---------------------+ +// | Authority | RRs pointing toward an authority +// +---------------------+ +// | Additional | RRs holding additional information +// +---------------------+ +// +// DNS Header +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | ID | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// |QR| Opcode |AA|TC|RD|RA| Z | RCODE | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | QDCOUNT | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | ANCOUNT | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | NSCOUNT | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | ARCOUNT | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +// DNS contains data from a single Domain Name Service packet. +type DNS struct { + BaseLayer + + // Header fields + ID uint16 + QR bool + OpCode DNSOpCode + + AA bool // Authoritative answer + TC bool // Truncated + RD bool // Recursion desired + RA bool // Recursion available + Z uint8 // Resrved for future use + + ResponseCode DNSResponseCode + QDCount uint16 // Number of questions to expect + ANCount uint16 // Number of answers to expect + NSCount uint16 // Number of authorities to expect + ARCount uint16 // Number of additional records to expect + + // Entries + Questions []DNSQuestion + Answers []DNSResourceRecord + Authorities []DNSResourceRecord + Additionals []DNSResourceRecord + + // buffer for doing name decoding. We use a single reusable buffer to avoid + // name decoding on a single object via multiple DecodeFromBytes calls + // requiring constant allocation of small byte slices. + buffer []byte +} + +// LayerType returns gopacket.LayerTypeDNS. +func (d *DNS) LayerType() gopacket.LayerType { return LayerTypeDNS } + +// decodeDNS decodes the byte slice into a DNS type. It also +// setups the application Layer in PacketBuilder. +func decodeDNS(data []byte, p gopacket.PacketBuilder) error { + d := &DNS{} + err := d.DecodeFromBytes(data, p) + if err != nil { + return err + } + p.AddLayer(d) + p.SetApplicationLayer(d) + return nil +} + +// DecodeFromBytes decodes the slice into the DNS struct. +func (d *DNS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + d.buffer = d.buffer[:0] + + if len(data) < 12 { + df.SetTruncated() + return errors.New("DNS packet too short") + } + + // since there are no further layers, the baselayer's content is + // pointing to this layer + d.BaseLayer = BaseLayer{Contents: data[:len(data)]} + d.ID = binary.BigEndian.Uint16(data[:2]) + d.QR = data[2]&0x80 != 0 + d.OpCode = DNSOpCode(data[2]>>3) & 0x0F + d.AA = data[2]&0x04 != 0 + d.TC = data[2]&0x02 != 0 + d.RD = data[2]&0x01 != 0 + d.RA = data[3]&0x80 != 0 + d.Z = uint8(data[3]>>4) & 0x7 + d.ResponseCode = DNSResponseCode(data[3] & 0xF) + d.QDCount = binary.BigEndian.Uint16(data[4:6]) + d.ANCount = binary.BigEndian.Uint16(data[6:8]) + d.NSCount = binary.BigEndian.Uint16(data[8:10]) + d.ARCount = binary.BigEndian.Uint16(data[10:12]) + + d.Questions = d.Questions[:0] + d.Answers = d.Answers[:0] + d.Authorities = d.Authorities[:0] + d.Additionals = d.Additionals[:0] + + offset := 12 + var err error + for i := 0; i < int(d.QDCount); i++ { + var q DNSQuestion + if offset, err = q.decode(data, offset, df, &d.buffer); err != nil { + return err + } + d.Questions = append(d.Questions, q) + } + + // For some horrible reason, if we do the obvious thing in this loop: + // var r DNSResourceRecord + // if blah := r.decode(blah); err != nil { + // return err + // } + // d.Foo = append(d.Foo, r) + // the Go compiler thinks that 'r' escapes to the heap, causing a malloc for + // every Answer, Authority, and Additional. To get around this, we do + // something really silly: we append an empty resource record to our slice, + // then use the last value in the slice to call decode. Since the value is + // already in the slice, there's no WAY it can escape... on the other hand our + // code is MUCH uglier :( + for i := 0; i < int(d.ANCount); i++ { + d.Answers = append(d.Answers, DNSResourceRecord{}) + if offset, err = d.Answers[i].decode(data, offset, df, &d.buffer); err != nil { + d.Answers = d.Answers[:i] // strip off erroneous value + return err + } + } + for i := 0; i < int(d.NSCount); i++ { + d.Authorities = append(d.Authorities, DNSResourceRecord{}) + if offset, err = d.Authorities[i].decode(data, offset, df, &d.buffer); err != nil { + d.Authorities = d.Authorities[:i] // strip off erroneous value + return err + } + } + for i := 0; i < int(d.ARCount); i++ { + d.Additionals = append(d.Additionals, DNSResourceRecord{}) + if offset, err = d.Additionals[i].decode(data, offset, df, &d.buffer); err != nil { + d.Additionals = d.Additionals[:i] // strip off erroneous value + return err + } + } + + if uint16(len(d.Questions)) != d.QDCount { + return errors.New("Invalid query decoding, not the right number of questions") + } else if uint16(len(d.Answers)) != d.ANCount { + return errors.New("Invalid query decoding, not the right number of answers") + } else if uint16(len(d.Authorities)) != d.NSCount { + return errors.New("Invalid query decoding, not the right number of authorities") + } else if uint16(len(d.Additionals)) != d.ARCount { + return errors.New("Invalid query decoding, not the right number of additionals info") + } + return nil +} + +// CanDecode implements gopacket.DecodingLayer. +func (d *DNS) CanDecode() gopacket.LayerClass { + return LayerTypeDNS +} + +// NextLayerType implements gopacket.DecodingLayer. +func (d *DNS) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypePayload +} + +// Payload returns nil. +func (d *DNS) Payload() []byte { + return nil +} + +func b2i(b bool) int { + if b { + return 1 + } + return 0 +} + +func recSize(rr *DNSResourceRecord) int { + switch rr.Type { + case DNSTypeA: + return 4 + case DNSTypeAAAA: + return 16 + case DNSTypeNS: + return len(rr.NS) + 2 + case DNSTypeCNAME: + return len(rr.CNAME) + 2 + case DNSTypePTR: + return len(rr.PTR) + 2 + case DNSTypeSOA: + return len(rr.SOA.MName) + 2 + len(rr.SOA.RName) + 2 + 20 + case DNSTypeMX: + return 2 + len(rr.MX.Name) + 2 + case DNSTypeTXT: + l := len(rr.TXTs) + for _, txt := range rr.TXTs { + l += len(txt) + } + return l + case DNSTypeSRV: + return 6 + len(rr.SRV.Name) + 2 + } + + return 0 +} + +func computeSize(recs []DNSResourceRecord) int { + sz := 0 + for _, rr := range recs { + sz += len(rr.Name) + 14 + sz += recSize(&rr) + } + return sz +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +func (d *DNS) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + dsz := 0 + for _, q := range d.Questions { + dsz += len(q.Name) + 6 + } + dsz += computeSize(d.Answers) + dsz += computeSize(d.Authorities) + dsz += computeSize(d.Additionals) + + bytes, err := b.PrependBytes(12 + dsz) + if err != nil { + return err + } + binary.BigEndian.PutUint16(bytes, d.ID) + bytes[2] = byte((b2i(d.QR) << 7) | (int(d.OpCode) << 3) | (b2i(d.AA) << 2) | (b2i(d.TC) << 1) | b2i(d.RD)) + bytes[3] = byte((b2i(d.RA) << 7) | (int(d.Z) << 4) | int(d.ResponseCode)) + + if opts.FixLengths { + d.QDCount = uint16(len(d.Questions)) + d.ANCount = uint16(len(d.Answers)) + d.NSCount = uint16(len(d.Authorities)) + d.ARCount = uint16(len(d.Additionals)) + } + binary.BigEndian.PutUint16(bytes[4:], d.QDCount) + binary.BigEndian.PutUint16(bytes[6:], d.ANCount) + binary.BigEndian.PutUint16(bytes[8:], d.NSCount) + binary.BigEndian.PutUint16(bytes[10:], d.ARCount) + + off := 12 + for _, qd := range d.Questions { + n := qd.encode(bytes, off) + off += n + } + + for i := range d.Answers { + // done this way so we can modify DNSResourceRecord to fix + // lengths if requested + qa := &d.Answers[i] + n, err := qa.encode(bytes, off, opts) + if err != nil { + return err + } + off += n + } + + for i := range d.Authorities { + qa := &d.Authorities[i] + n, err := qa.encode(bytes, off, opts) + if err != nil { + return err + } + off += n + } + for i := range d.Additionals { + qa := &d.Additionals[i] + n, err := qa.encode(bytes, off, opts) + if err != nil { + return err + } + off += n + } + + return nil +} + +var errMaxRecursion = errors.New("max DNS recursion level hit") + +const maxRecursionLevel = 255 + +func decodeName(data []byte, offset int, buffer *[]byte, level int) ([]byte, int, error) { + if level > maxRecursionLevel { + return nil, 0, errMaxRecursion + } else if offset >= len(data) { + return nil, 0, errors.New("dns name offset too high") + } else if offset < 0 { + return nil, 0, errors.New("dns name offset is negative") + } + start := len(*buffer) + index := offset + if data[index] == 0x00 { + return nil, index + 1, nil + } +loop: + for data[index] != 0x00 { + switch data[index] & 0xc0 { + default: + /* RFC 1035 + A domain name represented as a sequence of labels, where + each label consists of a length octet followed by that + number of octets. The domain name terminates with the + zero length octet for the null label of the root. Note + that this field may be an odd number of octets; no + padding is used. + */ + index2 := index + int(data[index]) + 1 + if index2-offset > 255 { + return nil, 0, errors.New("dns name is too long") + } else if index2 < index+1 || index2 > len(data) { + return nil, 0, errors.New("dns name uncomputable: invalid index") + } + *buffer = append(*buffer, '.') + *buffer = append(*buffer, data[index+1:index2]...) + index = index2 + + case 0xc0: + /* RFC 1035 + The pointer takes the form of a two octet sequence. + + The first two bits are ones. This allows a pointer to + be distinguished from a label, since the label must + begin with two zero bits because labels are restricted + to 63 octets or less. (The 10 and 01 combinations are + reserved for future use.) The OFFSET field specifies + an offset from the start of the message (i.e., the + first octet of the ID field in the domain header). A + zero offset specifies the first byte of the ID field, + etc. + + The compression scheme allows a domain name in a message to be + represented as either: + - a sequence of labels ending in a zero octet + - a pointer + - a sequence of labels ending with a pointer + */ + if index+2 > len(data) { + return nil, 0, errors.New("dns offset pointer too high") + } + offsetp := int(binary.BigEndian.Uint16(data[index:index+2]) & 0x3fff) + if offsetp > len(data) { + return nil, 0, errors.New("dns offset pointer too high") + } + // This looks a little tricky, but actually isn't. Because of how + // decodeName is written, calling it appends the decoded name to the + // current buffer. We already have the start of the buffer, then, so + // once this call is done buffer[start:] will contain our full name. + _, _, err := decodeName(data, offsetp, buffer, level+1) + if err != nil { + return nil, 0, err + } + index++ // pointer is two bytes, so add an extra byte here. + break loop + /* EDNS, or other DNS option ? */ + case 0x40: // RFC 2673 + return nil, 0, fmt.Errorf("qname '0x40' - RFC 2673 unsupported yet (data=%x index=%d)", + data[index], index) + + case 0x80: + return nil, 0, fmt.Errorf("qname '0x80' unsupported yet (data=%x index=%d)", + data[index], index) + } + if index >= len(data) { + return nil, 0, errors.New("dns index walked out of range") + } + } + if len(*buffer) <= start { + return nil, 0, errors.New("no dns data found for name") + } + return (*buffer)[start+1:], index + 1, nil +} + +// DNSQuestion wraps a single request (question) within a DNS query. +type DNSQuestion struct { + Name []byte + Type DNSType + Class DNSClass +} + +func (q *DNSQuestion) decode(data []byte, offset int, df gopacket.DecodeFeedback, buffer *[]byte) (int, error) { + name, endq, err := decodeName(data, offset, buffer, 1) + if err != nil { + return 0, err + } + + q.Name = name + q.Type = DNSType(binary.BigEndian.Uint16(data[endq : endq+2])) + q.Class = DNSClass(binary.BigEndian.Uint16(data[endq+2 : endq+4])) + + return endq + 4, nil +} + +func (q *DNSQuestion) encode(data []byte, offset int) int { + noff := encodeName(q.Name, data, offset) + binary.BigEndian.PutUint16(data[noff:], uint16(q.Type)) + binary.BigEndian.PutUint16(data[noff+2:], uint16(q.Class)) + return len(q.Name) + 6 +} + +// DNSResourceRecord +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | | +// / / +// / NAME / +// | | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | TYPE | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | CLASS | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | TTL | +// | | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | RDLENGTH | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--| +// / RDATA / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +// DNSResourceRecord wraps the data from a single DNS resource within a +// response. +type DNSResourceRecord struct { + // Header + Name []byte + Type DNSType + Class DNSClass + TTL uint32 + + // RDATA Raw Values + DataLength uint16 + Data []byte + + // RDATA Decoded Values + IP net.IP + NS, CNAME, PTR []byte + TXTs [][]byte + SOA DNSSOA + SRV DNSSRV + MX DNSMX + + // Undecoded TXT for backward compatibility + TXT []byte +} + +// decode decodes the resource record, returning the total length of the record. +func (rr *DNSResourceRecord) decode(data []byte, offset int, df gopacket.DecodeFeedback, buffer *[]byte) (int, error) { + name, endq, err := decodeName(data, offset, buffer, 1) + if err != nil { + return 0, err + } + + rr.Name = name + rr.Type = DNSType(binary.BigEndian.Uint16(data[endq : endq+2])) + rr.Class = DNSClass(binary.BigEndian.Uint16(data[endq+2 : endq+4])) + rr.TTL = binary.BigEndian.Uint32(data[endq+4 : endq+8]) + rr.DataLength = binary.BigEndian.Uint16(data[endq+8 : endq+10]) + end := endq + 10 + int(rr.DataLength) + if end > len(data) { + return 0, fmt.Errorf("resource record length exceeds data") + } + rr.Data = data[endq+10 : end] + + if err = rr.decodeRData(data, endq+10, buffer); err != nil { + return 0, err + } + + return endq + 10 + int(rr.DataLength), nil +} + +func encodeName(name []byte, data []byte, offset int) int { + l := 0 + for i := range name { + if name[i] == '.' { + data[offset+i-l] = byte(l) + l = 0 + } else { + // skip one to write the length + data[offset+i+1] = name[i] + l++ + } + } + // length for final portion + data[offset+len(name)-l] = byte(l) + data[offset+len(name)+1] = 0x00 // terminal + return offset + len(name) + 2 +} + +func (rr *DNSResourceRecord) encode(data []byte, offset int, opts gopacket.SerializeOptions) (int, error) { + + noff := encodeName(rr.Name, data, offset) + + binary.BigEndian.PutUint16(data[noff:], uint16(rr.Type)) + binary.BigEndian.PutUint16(data[noff+2:], uint16(rr.Class)) + binary.BigEndian.PutUint32(data[noff+4:], uint32(rr.TTL)) + + switch rr.Type { + case DNSTypeA: + copy(data[noff+10:], rr.IP.To4()) + case DNSTypeAAAA: + copy(data[noff+10:], rr.IP) + case DNSTypeNS: + encodeName(rr.NS, data, noff+10) + case DNSTypeCNAME: + encodeName(rr.CNAME, data, noff+10) + case DNSTypePTR: + encodeName(rr.PTR, data, noff+10) + case DNSTypeSOA: + noff2 := encodeName(rr.SOA.MName, data, noff+10) + noff2 = encodeName(rr.SOA.RName, data, noff2) + binary.BigEndian.PutUint32(data[noff2:], rr.SOA.Serial) + binary.BigEndian.PutUint32(data[noff2+4:], rr.SOA.Refresh) + binary.BigEndian.PutUint32(data[noff2+8:], rr.SOA.Retry) + binary.BigEndian.PutUint32(data[noff2+12:], rr.SOA.Expire) + binary.BigEndian.PutUint32(data[noff2+16:], rr.SOA.Minimum) + case DNSTypeMX: + binary.BigEndian.PutUint16(data[noff+10:], rr.MX.Preference) + encodeName(rr.MX.Name, data, noff+12) + case DNSTypeTXT: + noff2 := noff + 10 + for _, txt := range rr.TXTs { + data[noff2] = byte(len(txt)) + copy(data[noff2+1:], txt) + noff2 += 1 + len(txt) + } + case DNSTypeSRV: + binary.BigEndian.PutUint16(data[noff+10:], rr.SRV.Priority) + binary.BigEndian.PutUint16(data[noff+12:], rr.SRV.Weight) + binary.BigEndian.PutUint16(data[noff+14:], rr.SRV.Port) + encodeName(rr.SRV.Name, data, noff+16) + default: + return 0, fmt.Errorf("serializing resource record of type %v not supported", rr.Type) + } + + // DataLength + dSz := recSize(rr) + binary.BigEndian.PutUint16(data[noff+8:], uint16(dSz)) + + if opts.FixLengths { + rr.DataLength = uint16(dSz) + } + + return len(rr.Name) + 1 + 11 + dSz, nil +} + +func (rr *DNSResourceRecord) String() string { + + if rr.Class == DNSClassIN { + switch rr.Type { + case DNSTypeA, DNSTypeAAAA: + return rr.IP.String() + case DNSTypeNS: + return "NS " + string(rr.NS) + case DNSTypeCNAME: + return "CNAME " + string(rr.CNAME) + case DNSTypePTR: + return "PTR " + string(rr.PTR) + case DNSTypeTXT: + return "TXT " + string(rr.TXT) + } + } + + return fmt.Sprintf("<%v, %v>", rr.Class, rr.Type) +} + +func decodeCharacterStrings(data []byte) ([][]byte, error) { + strings := make([][]byte, 0, 1) + end := len(data) + for index, index2 := 0, 0; index != end; index = index2 { + index2 = index + 1 + int(data[index]) // index increases by 1..256 and does not overflow + if index2 > end { + return nil, errors.New("Insufficient data for a <character-string>") + } + strings = append(strings, data[index+1:index2]) + } + return strings, nil +} + +func (rr *DNSResourceRecord) decodeRData(data []byte, offset int, buffer *[]byte) error { + switch rr.Type { + case DNSTypeA: + rr.IP = rr.Data + case DNSTypeAAAA: + rr.IP = rr.Data + case DNSTypeTXT, DNSTypeHINFO: + rr.TXT = rr.Data + txts, err := decodeCharacterStrings(rr.Data) + if err != nil { + return err + } + rr.TXTs = txts + case DNSTypeNS: + name, _, err := decodeName(data, offset, buffer, 1) + if err != nil { + return err + } + rr.NS = name + case DNSTypeCNAME: + name, _, err := decodeName(data, offset, buffer, 1) + if err != nil { + return err + } + rr.CNAME = name + case DNSTypePTR: + name, _, err := decodeName(data, offset, buffer, 1) + if err != nil { + return err + } + rr.PTR = name + case DNSTypeSOA: + name, endq, err := decodeName(data, offset, buffer, 1) + if err != nil { + return err + } + rr.SOA.MName = name + name, endq, err = decodeName(data, endq, buffer, 1) + if err != nil { + return err + } + rr.SOA.RName = name + rr.SOA.Serial = binary.BigEndian.Uint32(data[endq : endq+4]) + rr.SOA.Refresh = binary.BigEndian.Uint32(data[endq+4 : endq+8]) + rr.SOA.Retry = binary.BigEndian.Uint32(data[endq+8 : endq+12]) + rr.SOA.Expire = binary.BigEndian.Uint32(data[endq+12 : endq+16]) + rr.SOA.Minimum = binary.BigEndian.Uint32(data[endq+16 : endq+20]) + case DNSTypeMX: + rr.MX.Preference = binary.BigEndian.Uint16(data[offset : offset+2]) + name, _, err := decodeName(data, offset+2, buffer, 1) + if err != nil { + return err + } + rr.MX.Name = name + case DNSTypeSRV: + rr.SRV.Priority = binary.BigEndian.Uint16(data[offset : offset+2]) + rr.SRV.Weight = binary.BigEndian.Uint16(data[offset+2 : offset+4]) + rr.SRV.Port = binary.BigEndian.Uint16(data[offset+4 : offset+6]) + name, _, err := decodeName(data, offset+6, buffer, 1) + if err != nil { + return err + } + rr.SRV.Name = name + } + return nil +} + +// DNSSOA is a Start of Authority record. Each domain requires a SOA record at +// the cutover where a domain is delegated from its parent. +type DNSSOA struct { + MName, RName []byte + Serial, Refresh, Retry, Expire, Minimum uint32 +} + +// DNSSRV is a Service record, defining a location (hostname/port) of a +// server/service. +type DNSSRV struct { + Priority, Weight, Port uint16 + Name []byte +} + +// DNSMX is a mail exchange record, defining a mail server for a recipient's +// domain. +type DNSMX struct { + Preference uint16 + Name []byte +} diff --git a/vendor/github.com/google/gopacket/layers/dns_test.go b/vendor/github.com/google/gopacket/layers/dns_test.go new file mode 100644 index 0000000..264513b --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/dns_test.go @@ -0,0 +1,833 @@ +// Copyright 2012, Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "bytes" + "net" + "strings" + "testing" + + "github.com/google/gopacket" +) + +// testPacketDNSRegression is the packet: +// 11:08:05.708342 IP 109.194.160.4.57766 > 95.211.92.14.53: 63000% [1au] A? picslife.ru. (40) +// 0x0000: 0022 19b6 7e22 000f 35bb 0b40 0800 4500 ."..~"..5..@..E. +// 0x0010: 0044 89c4 0000 3811 2f3d 6dc2 a004 5fd3 .D....8./=m..._. +// 0x0020: 5c0e e1a6 0035 0030 a597 f618 0010 0001 \....5.0........ +// 0x0030: 0000 0000 0001 0870 6963 736c 6966 6502 .......picslife. +// 0x0040: 7275 0000 0100 0100 0029 1000 0000 8000 ru.......)...... +// 0x0050: 0000 .. +var testPacketDNSRegression = []byte{ + 0x00, 0x22, 0x19, 0xb6, 0x7e, 0x22, 0x00, 0x0f, 0x35, 0xbb, 0x0b, 0x40, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x44, 0x89, 0xc4, 0x00, 0x00, 0x38, 0x11, 0x2f, 0x3d, 0x6d, 0xc2, 0xa0, 0x04, 0x5f, 0xd3, + 0x5c, 0x0e, 0xe1, 0xa6, 0x00, 0x35, 0x00, 0x30, 0xa5, 0x97, 0xf6, 0x18, 0x00, 0x10, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x70, 0x69, 0x63, 0x73, 0x6c, 0x69, 0x66, 0x65, 0x02, + 0x72, 0x75, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x29, 0x10, 0x00, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x00, +} + +func TestPacketDNSRegression(t *testing.T) { + p := gopacket.NewPacket(testPacketDNSRegression, LinkTypeEthernet, testDecodeOptions) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeUDP, LayerTypeDNS}, t) +} +func BenchmarkDecodePacketDNSRegression(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketDNSRegression, LinkTypeEthernet, gopacket.NoCopy) + } +} + +// response to `dig TXT google.com` over IPv4 link: +var testParseDNSTypeTXTValue = `v=spf1 include:_spf.google.com ~all` +var testParseDNSTypeTXT = []byte{ + 0x02, 0x00, 0x00, 0x00, // PF_INET + 0x45, 0x00, 0x00, 0x73, 0x00, 0x00, 0x40, 0x00, 0x39, 0x11, 0x64, 0x98, 0xd0, 0x43, 0xde, 0xde, + 0x0a, 0xba, 0x23, 0x06, 0x00, 0x35, 0x81, 0xb2, 0x00, 0x5f, 0xdc, 0xb5, 0x98, 0x71, 0x81, 0x80, + 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, + 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x10, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, + 0x0e, 0x10, 0x00, 0x24, 0x23, 0x76, 0x3d, 0x73, 0x70, 0x66, 0x31, 0x20, 0x69, 0x6e, 0x63, 0x6c, + 0x75, 0x64, 0x65, 0x3a, 0x5f, 0x73, 0x70, 0x66, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x63, 0x6f, 0x6d, 0x20, 0x7e, 0x61, 0x6c, 0x6c, 0x00, 0x00, 0x29, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, +} + +func TestParseDNSTypeTXT(t *testing.T) { + p := gopacket.NewPacket(testParseDNSTypeTXT, LinkTypeNull, testDecodeOptions) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeLoopback, LayerTypeIPv4, LayerTypeUDP, LayerTypeDNS}, t) + answers := p.Layer(LayerTypeDNS).(*DNS).Answers + if len(answers) != 1 { + t.Error("Failed to parse 1 DNS answer") + } + if len(answers[0].TXTs) != 1 { + t.Error("Failed to parse 1 TXT record") + } + txt := string(answers[0].TXTs[0]) + if txt != testParseDNSTypeTXTValue { + t.Errorf("Incorrect TXT value, expected %q, got %q", testParseDNSTypeTXTValue, txt) + } +} + +func testQuestionEqual(t *testing.T, i int, exp, got DNSQuestion) { + if !bytes.Equal(exp.Name, got.Name) { + t.Errorf("expected Questions[%d].Name = %v, got %v", i, string(exp.Name), string(got.Name)) + } + if exp.Type != got.Type { + t.Errorf("expected Questions[%d].Type = %v, got %v", i, exp.Type, got.Type) + } + if exp.Class != got.Class { + t.Errorf("expected Questions[%d].Class = %v, got %v", i, exp.Class, got.Class) + } +} + +func testResourceEqual(t *testing.T, i int, name string, exp, got DNSResourceRecord) { + if !bytes.Equal(exp.Name, got.Name) { + t.Errorf("expected %s[%d].Name = %v, got %v", name, i, string(exp.Name), string(got.Name)) + } + + if exp.Type != got.Type { + t.Errorf("expected %s[%d].Type = %v, got %v", name, i, exp.Type, got.Type) + } + + if exp.Class != got.Class { + t.Errorf("expected %s[%d].Class = %v, got %v", name, i, exp.Class, got.Class) + } + + if exp.TTL != got.TTL { + t.Errorf("expected %s[%d].TTL = %v, got %v", name, i, exp.TTL, got.TTL) + } + if exp.DataLength != got.DataLength { + t.Errorf("expected %s[%d].DataLength = %v, got %v", name, i, exp.DataLength, got.DataLength) + } + + // we don't check .Data + + if !exp.IP.Equal(got.IP) { + t.Errorf("expected %s[%d].IP = %v, got %v", name, i, exp.IP, got.IP) + } + if !bytes.Equal(exp.NS, got.NS) { + t.Errorf("expected %s[%d].NS = %v, got %v", name, i, exp.NS, got.NS) + } + if !bytes.Equal(exp.CNAME, got.CNAME) { + t.Errorf("expected %s[%d].CNAME = %v, got %v", name, i, exp.CNAME, got.CNAME) + } + if !bytes.Equal(exp.PTR, got.PTR) { + t.Errorf("expected %s[%d].PTR = %v, got %v", name, i, exp.PTR, got.PTR) + } + if len(exp.TXTs) != len(got.TXTs) { + t.Errorf("expected %s[%d].TXTs = %v, got %v", name, i, exp.TXTs, got.TXTs) + } + for j := range exp.TXTs { + if !bytes.Equal(exp.TXTs[j], got.TXTs[j]) { + t.Errorf("expected %s[%d].TXTs[%d] = %v, got %v", name, i, j, exp.TXTs[j], got.TXTs[j]) + } + } + + // SOA + if !bytes.Equal(exp.SOA.MName, got.SOA.MName) { + t.Errorf("expected %s[%d].SOA.MName = %v, got %v", name, i, exp.SOA.MName, got.SOA.MName) + } + if !bytes.Equal(exp.SOA.RName, got.SOA.RName) { + t.Errorf("expected %s[%d].SOA.RName = %v, got %v", name, i, exp.SOA.RName, got.SOA.RName) + } + if exp.SOA.Serial != got.SOA.Serial { + t.Errorf("expected %s[%d].SOA.Serial = %v, got %v", name, i, exp.SOA.Serial, got.SOA.Serial) + } + if exp.SOA.Refresh != got.SOA.Refresh { + t.Errorf("expected %s[%d].SOA.Refresh = %v, got %v", name, i, exp.SOA.Refresh, got.SOA.Refresh) + } + if exp.SOA.Retry != got.SOA.Retry { + t.Errorf("expected %s[%d].SOA.Retry = %v, got %v", name, i, exp.SOA.Retry, got.SOA.Retry) + } + if exp.SOA.Expire != got.SOA.Expire { + t.Errorf("expected %s[%d].SOA.Expire = %v, got %v", name, i, exp.SOA.Expire, got.SOA.Expire) + } + if exp.SOA.Minimum != got.SOA.Minimum { + t.Errorf("expected %s[%d].SOA.Minimum = %v, got %v", name, i, exp.SOA.Minimum, got.SOA.Minimum) + } + + // SRV + if !bytes.Equal(exp.SRV.Name, got.SRV.Name) { + t.Errorf("expected %s[%d].SRV.Name = %v, got %v", name, i, exp.SRV.Name, got.SRV.Name) + } + if exp.SRV.Weight != got.SRV.Weight { + t.Errorf("expected %s[%d].SRV.Weight = %v, got %v", name, i, exp.SRV.Weight, got.SRV.Weight) + } + if exp.SRV.Port != got.SRV.Port { + t.Errorf("expected %s[%d].SRV.Port = %v, got %v", name, i, exp.SRV.Port, got.SRV.Port) + } + // MX + if !bytes.Equal(exp.MX.Name, got.MX.Name) { + t.Errorf("expected %s[%d].MX.Name = %v, got %v", name, i, exp.MX.Name, got.MX.Name) + } + if exp.MX.Preference != got.MX.Preference { + t.Errorf("expected %s[%d].MX.Preference = %v, got %v", name, i, exp.MX.Preference, got.MX.Preference) + } +} + +func testDNSEqual(t *testing.T, exp, got *DNS) { + if exp.ID != got.ID { + t.Errorf("expected ID = %v, got %v", exp.ID, got.ID) + } + if exp.AA != got.AA { + t.Errorf("expected AA = %v, got %v", exp.AA, got.AA) + } + if exp.OpCode != got.OpCode { + t.Errorf("expected OpCode = %v, got %v", exp.OpCode, got.OpCode) + } + if exp.AA != got.AA { + t.Errorf("expected AA = %v, got %v", exp.AA, got.AA) + } + if exp.TC != got.TC { + t.Errorf("expected TC = %v, got %v", exp.TC, got.TC) + } + if exp.RD != got.RD { + t.Errorf("expected RD = %v, got %v", exp.RD, got.RD) + } + if exp.RA != got.RA { + t.Errorf("expected RA = %v, got %v", exp.RA, got.RA) + } + if exp.Z != got.Z { + t.Errorf("expected Z = %v, got %v", exp.Z, got.Z) + } + if exp.ResponseCode != got.ResponseCode { + t.Errorf("expected ResponseCode = %v, got %v", exp.ResponseCode, got.ResponseCode) + } + if exp.QDCount != got.QDCount { + t.Errorf("expected QDCount = %v, got %v", exp.QDCount, got.QDCount) + } + if exp.ANCount != got.ANCount { + t.Errorf("expected ANCount = %v, got %v", exp.ANCount, got.ANCount) + } + if exp.ANCount != got.ANCount { + t.Errorf("expected ANCount = %v, got %v", exp.ANCount, got.ANCount) + } + if exp.NSCount != got.NSCount { + t.Errorf("expected NSCount = %v, got %v", exp.NSCount, got.NSCount) + } + if exp.ARCount != got.ARCount { + t.Errorf("expected ARCount = %v, got %v", exp.ARCount, got.ARCount) + } + + if len(exp.Questions) != len(got.Questions) { + t.Errorf("expected %d Questions, got %d", len(exp.Questions), len(got.Questions)) + } + for i := range exp.Questions { + testQuestionEqual(t, i, exp.Questions[i], got.Questions[i]) + } + + if len(exp.Answers) != len(got.Answers) { + t.Errorf("expected %d Answers, got %d", len(exp.Answers), len(got.Answers)) + } + for i := range exp.Answers { + testResourceEqual(t, i, "Answers", exp.Answers[i], got.Answers[i]) + } + + if len(exp.Authorities) != len(got.Authorities) { + t.Errorf("expected %d Answers, got %d", len(exp.Authorities), len(got.Authorities)) + } + for i := range exp.Authorities { + testResourceEqual(t, i, "Authorities", exp.Authorities[i], got.Authorities[i]) + } + + if len(exp.Additionals) != len(got.Additionals) { + t.Errorf("expected %d Additionals, got %d", len(exp.Additionals), len(got.Additionals)) + } + for i := range exp.Additionals { + testResourceEqual(t, i, "Additionals", exp.Additionals[i], got.Additionals[i]) + } +} + +func TestDNSEncodeQuery(t *testing.T) { + dns := &DNS{ID: 1234, OpCode: DNSOpCodeQuery, RD: true} + dns.Questions = append(dns.Questions, + DNSQuestion{ + Name: []byte("example1.com"), + Type: DNSTypeA, + Class: DNSClassIN, + }) + + dns.Questions = append(dns.Questions, + DNSQuestion{ + Name: []byte("example2.com"), + Type: DNSTypeA, + Class: DNSClassIN, + }) + + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{FixLengths: true} + err := gopacket.SerializeLayers(buf, opts, dns) + if err != nil { + t.Fatal(err) + } + if int(dns.QDCount) != len(dns.Questions) { + t.Errorf("fix lengths did not adjust QDCount, expected %d got %d", len(dns.Questions), dns.QDCount) + } + + p2 := gopacket.NewPacket(buf.Bytes(), LayerTypeDNS, testDecodeOptions) + dns2 := p2.Layer(LayerTypeDNS).(*DNS) + testDNSEqual(t, dns, dns2) +} + +func TestDNSEncodeResponse(t *testing.T) { + dns := &DNS{ID: 1234, QR: true, OpCode: DNSOpCodeQuery, + AA: true, RD: true, RA: true} + dns.Questions = append(dns.Questions, + DNSQuestion{ + Name: []byte("example1.com"), + Type: DNSTypeA, + Class: DNSClassIN, + }) + dns.Questions = append(dns.Questions, + DNSQuestion{ + Name: []byte("www.example2.com"), + Type: DNSTypeAAAA, + Class: DNSClassIN, + }) + + dns.Answers = append(dns.Answers, + DNSResourceRecord{ + Name: []byte("example1.com"), + Type: DNSTypeA, + Class: DNSClassIN, + TTL: 1024, + IP: net.IP([]byte{1, 2, 3, 4}), + }) + + dns.Answers = append(dns.Answers, + DNSResourceRecord{ + Name: []byte("www.example2.com"), + Type: DNSTypeAAAA, + Class: DNSClassIN, + TTL: 1024, + IP: net.IP([]byte{5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4}), + }) + + dns.Answers = append(dns.Answers, + DNSResourceRecord{ + Name: []byte("www.example2.com"), + Type: DNSTypeCNAME, + Class: DNSClassIN, + TTL: 1024, + CNAME: []byte("example2.com"), + }) + + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{FixLengths: true} + err := gopacket.SerializeLayers(buf, opts, dns) + if err != nil { + t.Fatal(err) + } + if int(dns.ANCount) != len(dns.Answers) { + t.Errorf("fix lengths did not adjust ANCount, expected %d got %d", len(dns.Answers), dns.ANCount) + } + for i, a := range dns.Answers { + if a.DataLength == 0 { + t.Errorf("fix lengths did not adjust Answers[%d].DataLength", i) + } + } + + p2 := gopacket.NewPacket(buf.Bytes(), LayerTypeDNS, testDecodeOptions) + dns2 := p2.Layer(LayerTypeDNS).(*DNS) + testDNSEqual(t, dns, dns2) +} + +// testDNSMalformedPacket is the packet: +// 10:30:00.389666 IP 10.77.43.131.60718 > 10.1.0.17.53: 18245 updateD [b2&3=0x5420] [18516a] [12064q] [21584n] [12081au][|domain] +// 0x0000: 0000 0101 0000 4e96 1476 afa1 0800 4500 ......N..v....E. +// 0x0010: 0039 d431 0000 f311 b3a0 0a4d 2b83 0a01 .9.1.......M+... +// 0x0020: 0011 ed2e 0035 0025 0832 4745 5420 2f20 .....5.%.2GET./. +// 0x0030: 4854 5450 2f31 2e31 0d0a 486f 7374 3a20 HTTP/1.1..Host:. +// 0x0040: 7777 770d 0a0d 0a www.... +var testDNSMalformedPacket = []byte{ + 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x4e, 0x96, 0x14, 0x76, 0xaf, 0xa1, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x39, 0xd4, 0x31, 0x00, 0x00, 0xf3, 0x11, 0xb3, 0xa0, 0x0a, 0x4d, 0x2b, 0x83, 0x0a, 0x01, + 0x00, 0x11, 0xed, 0x2e, 0x00, 0x35, 0x00, 0x25, 0x08, 0x32, 0x47, 0x45, 0x54, 0x20, 0x2f, 0x20, + 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, + 0x77, 0x77, 0x77, 0x0d, 0x0a, 0x0d, 0x0a, +} + +func TestDNSMalformedPacket(t *testing.T) { + p := gopacket.NewPacket(testDNSMalformedPacket, LinkTypeEthernet, testDecodeOptions) + if errLayer := p.ErrorLayer(); errLayer == nil { + t.Error("No error layer on invalid DNS name") + } else if err := errLayer.Error(); !strings.Contains(err.Error(), "invalid index") { + t.Errorf("unexpected error message: %v", err) + } +} + +// testDNSMalformedPacket2 is the packet: +// 15:14:42.056054 IP 10.77.0.245.53 > 10.1.0.45.38769: 12625 zoneInit YXRRSet- [49833q],[|domain] +// 0x0000: 0055 22af c637 0022 55ac deac 0800 4500 .U"..7."U.....E. +// 0x0010: 0079 3767 4000 3911 f49d 0a4d 00f5 0a01 .y7g@.9....M.... +// 0x0020: 002d 0035 9771 0065 6377 3151 f057 c2a9 .-.5.q.ecw1Q.W.. +// 0x0030: fc6e e86a beb0 f7d4 8599 373e b5f8 9db2 .n.j......7>.... +// 0x0040: a399 21a1 9762 def1 def4 f5ab 5675 023e ..!..b......Vu.> +// 0x0050: c9ca 304f 178a c2ad f2fc 677a 0e4c b892 ..0O......gz.L.. +// 0x0060: ab71 09bb 1ea4 f7c4 fe47 7a39 868b 29a0 .q.......Gz9..). +// 0x0070: 62c4 d184 5b4e 8817 4cc0 d1d0 d430 11d3 b...[N..L....0.. +// 0x0080: d147 543f afc7 1a .GT?... +var testDNSMalformedPacket2 = []byte{ + 0x00, 0x55, 0x22, 0xaf, 0xc6, 0x37, 0x00, 0x22, 0x55, 0xac, 0xde, 0xac, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x79, 0x37, 0x67, 0x40, 0x00, 0x39, 0x11, 0xf4, 0x9d, 0x0a, 0x4d, 0x00, 0xf5, 0x0a, 0x01, + 0x00, 0x2d, 0x00, 0x35, 0x97, 0x71, 0x00, 0x65, 0x63, 0x77, 0x31, 0x51, 0xf0, 0x57, 0xc2, 0xa9, + 0xfc, 0x6e, 0xe8, 0x6a, 0xbe, 0xb0, 0xf7, 0xd4, 0x85, 0x99, 0x37, 0x3e, 0xb5, 0xf8, 0x9d, 0xb2, + 0xa3, 0x99, 0x21, 0xa1, 0x97, 0x62, 0xde, 0xf1, 0xde, 0xf4, 0xf5, 0xab, 0x56, 0x75, 0x02, 0x3e, + 0xc9, 0xca, 0x30, 0x4f, 0x17, 0x8a, 0xc2, 0xad, 0xf2, 0xfc, 0x67, 0x7a, 0x0e, 0x4c, 0xb8, 0x92, + 0xab, 0x71, 0x09, 0xbb, 0x1e, 0xa4, 0xf7, 0xc4, 0xfe, 0x47, 0x7a, 0x39, 0x86, 0x8b, 0x29, 0xa0, + 0x62, 0xc4, 0xd1, 0x84, 0x5b, 0x4e, 0x88, 0x17, 0x4c, 0xc0, 0xd1, 0xd0, 0xd4, 0x30, 0x11, 0xd3, + 0xd1, 0x47, 0x54, 0x3f, 0xaf, 0xc7, 0x1a, +} + +func TestDNSMalformedPacket2(t *testing.T) { + p := gopacket.NewPacket(testDNSMalformedPacket2, LinkTypeEthernet, testDecodeOptions) + if errLayer := p.ErrorLayer(); errLayer == nil { + t.Error("No error layer on invalid DNS name") + } else if err := errLayer.Error(); !strings.Contains(err.Error(), "offset pointer too high") { + t.Errorf("unexpected error message: %v", err) + } +} + +// testMalformedRootQuery is the packet: +// 08:31:18.143065 IP 10.77.0.26.53 > 10.1.0.233.65071: 59508- 0/13/3 (508) +// 0x0000: 0055 22af c637 0022 55ac deac 0800 4500 .U"..7."U.....E. +// 0x0010: 0218 76b2 4000 7211 7ad2 0a4d 001a 0a01 ..v.@.r.z..M.... +// 0x0020: 00e9 0035 fe2f 0204 b8f5 e874 8100 0001 ...5./.....t.... +// 0x0030: 0000 000d 0003 0c61 786b 7663 6863 7063 .......axkvchcpc +// 0x0040: 7073 6c0a 7878 7878 7878 7878 7878 036e psl.xxxxxxxxxx.n +// 0x0050: 6574 0000 0100 0100 0002 0001 0000 0e10 et.............. +// 0x0060: 0014 016d 0c72 6f6f 742d 7365 7276 6572 ...m.root-server +// 0x0070: 7303 6e65 7400 c02d 0002 0001 0000 0e10 s.net..-........ +// 0x0080: 0014 0161 0c72 6f6f 742d 7365 7276 6572 ...a.root-server +// 0x0090: 7303 6e65 7400 c02d 0002 0001 0000 0e10 s.net..-........ +// 0x00a0: 0014 0169 0c72 6f6f 742d 7365 7276 6572 ...i.root-server +// 0x00b0: 7303 6e65 7400 c02d 0002 0001 0000 0e10 s.net..-........ +// 0x00c0: 0014 0162 0c72 6f6f 742d 7365 7276 6572 ...b.root-server +// 0x00d0: 7303 6e65 7400 c02d 0002 0001 0000 0e10 s.net..-........ +// 0x00e0: 0014 016c 0c72 6f6f 742d 7365 7276 6572 ...l.root-server +// 0x00f0: 7303 6e65 7400 c02d 0002 0001 0000 0e10 s.net..-........ +// 0x0100: 0014 0166 0c72 6f6f 742d 7365 7276 6572 ...f.root-server +// 0x0110: 7303 6e65 7400 c02d 0002 0001 0000 0e10 s.net..-........ +// 0x0120: 0014 0167 0c72 6f6f 742d 7365 7276 6572 ...g.root-server +// 0x0130: 7303 6e65 7400 c02d 0002 0001 0000 0e10 s.net..-........ +// 0x0140: 0014 0164 0c72 6f6f 742d 7365 7276 6572 ...d.root-server +// 0x0150: 7303 6e65 7400 c02d 0002 0001 0000 0e10 s.net..-........ +// 0x0160: 0014 0168 0c72 6f6f 742d 7365 7276 6572 ...h.root-server +// 0x0170: 7303 6e65 7400 c02d 0002 0001 0000 0e10 s.net..-........ +// 0x0180: 0014 0165 0c72 6f6f 742d 7365 7276 6572 ...e.root-server +// 0x0190: 7303 6e65 7400 c02d 0002 0001 0000 0e10 s.net..-........ +// 0x01a0: 0014 016a 0c72 6f6f 742d 7365 7276 6572 ...j.root-server +// 0x01b0: 7303 6e65 7400 c02d 0002 0001 0000 0e10 s.net..-........ +// 0x01c0: 0014 016b 0c72 6f6f 742d 7365 7276 6572 ...k.root-server +// 0x01d0: 7303 6e65 7400 c02d 0002 0001 0000 0e10 s.net..-........ +// 0x01e0: 0014 0163 0c72 6f6f 742d 7365 7276 6572 ...c.root-server +// 0x01f0: 7303 6e65 7400 c038 0001 0001 0000 0e10 s.net..8........ +// 0x0200: 0004 ca0c 1b21 c058 0001 0001 0000 0e10 .....!.X........ +// 0x0210: 0004 c629 0004 c078 0001 0001 0000 0e10 ...)...x........ +// 0x0220: 0004 c024 9411 ...$.. +var testMalformedRootQuery = []byte{ + 0x00, 0x55, 0x22, 0xaf, 0xc6, 0x37, 0x00, 0x22, 0x55, 0xac, 0xde, 0xac, 0x08, 0x00, 0x45, 0x00, + 0x02, 0x18, 0x76, 0xb2, 0x40, 0x00, 0x72, 0x11, 0x7a, 0xd2, 0x0a, 0x4d, 0x00, 0x1a, 0x0a, 0x01, + 0x00, 0xe9, 0x00, 0x35, 0xfe, 0x2f, 0x02, 0x04, 0xb8, 0xf5, 0xe8, 0x74, 0x81, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x0d, 0x00, 0x03, 0x0c, 0x61, 0x78, 0x6b, 0x76, 0x63, 0x68, 0x63, 0x70, 0x63, + 0x70, 0x73, 0x6c, 0x0a, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x03, 0x6e, + 0x65, 0x74, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, + 0x00, 0x14, 0x01, 0x6d, 0x0c, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x73, 0x03, 0x6e, 0x65, 0x74, 0x00, 0xc0, 0x2d, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, + 0x00, 0x14, 0x01, 0x61, 0x0c, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x73, 0x03, 0x6e, 0x65, 0x74, 0x00, 0xc0, 0x2d, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, + 0x00, 0x14, 0x01, 0x69, 0x0c, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x73, 0x03, 0x6e, 0x65, 0x74, 0x00, 0xc0, 0x2d, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, + 0x00, 0x14, 0x01, 0x62, 0x0c, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x73, 0x03, 0x6e, 0x65, 0x74, 0x00, 0xc0, 0x2d, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, + 0x00, 0x14, 0x01, 0x6c, 0x0c, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x73, 0x03, 0x6e, 0x65, 0x74, 0x00, 0xc0, 0x2d, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, + 0x00, 0x14, 0x01, 0x66, 0x0c, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x73, 0x03, 0x6e, 0x65, 0x74, 0x00, 0xc0, 0x2d, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, + 0x00, 0x14, 0x01, 0x67, 0x0c, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x73, 0x03, 0x6e, 0x65, 0x74, 0x00, 0xc0, 0x2d, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, + 0x00, 0x14, 0x01, 0x64, 0x0c, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x73, 0x03, 0x6e, 0x65, 0x74, 0x00, 0xc0, 0x2d, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, + 0x00, 0x14, 0x01, 0x68, 0x0c, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x73, 0x03, 0x6e, 0x65, 0x74, 0x00, 0xc0, 0x2d, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, + 0x00, 0x14, 0x01, 0x65, 0x0c, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x73, 0x03, 0x6e, 0x65, 0x74, 0x00, 0xc0, 0x2d, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, + 0x00, 0x14, 0x01, 0x6a, 0x0c, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x73, 0x03, 0x6e, 0x65, 0x74, 0x00, 0xc0, 0x2d, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, + 0x00, 0x14, 0x01, 0x6b, 0x0c, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x73, 0x03, 0x6e, 0x65, 0x74, 0x00, 0xc0, 0x2d, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, + 0x00, 0x14, 0x01, 0x63, 0x0c, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x73, 0x03, 0x6e, 0x65, 0x74, 0x00, 0xc0, 0x38, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, + 0x00, 0x04, 0xca, 0x0c, 0x1b, 0x21, 0xc0, 0x58, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, + 0x00, 0x04, 0xc6, 0x29, 0x00, 0x04, 0xc0, 0x78, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, + 0x00, 0x04, 0xc0, 0x24, 0x94, 0x11, +} + +func TestMalformedRootQuery(t *testing.T) { + p := gopacket.NewPacket(testMalformedRootQuery, LinkTypeEthernet, testDecodeOptions) + if errLayer := p.ErrorLayer(); errLayer == nil { + t.Error("No error layer on invalid DNS name") + } else if err := errLayer.Error(); !strings.Contains(err.Error(), "no dns data found") { + t.Errorf("unexpected error message: %v", err) + } +} + +// testAnotherMalformedDNS is the packet: +// 10:52:13.690904 IP 10.77.0.29.53 > 10.1.0.6.42280: 13491 op6+% [b2&3=0x3313] [11720a] [23583q] [29742n] [52087au] Type22277 (Class 43688)? M- M-<.VM-^KM-wQM-s"M-^E^]M-+^Wx^P^@M-^\^\M-oM-FM-U^F^E7M-tM-^VM-^[M-F^H>G^FM-uM-^KM-_6GM-[M-jM-bM-^H]hM-^J.[|domain] +// 0x0000: 0055 22af c637 0022 55ac deac 0800 4500 .U"..7."U.....E. +// 0x0010: 05c1 2eea 4000 3611 fbd1 0a4d 001d 0a01 ....@.6....M.... +// 0x0020: 0006 0035 a528 05ad 00a2 34b3 3313 5c1f ...5.(....4.3.\. +// 0x0030: 2dc8 742e cb77 2da0 bc2e 568b f751 f322 -.t..w-...V..Q." +// 0x0040: 851d ab17 7810 009c 1cef c6d5 0605 37f4 ....x.........7. +// 0x0050: 969b c65e 483e 4706 f58b df36 47db eae2 ...^H>G....6G... +// 0x0060: 885d 688a c5a5 5705 aaa8 95eb 93a4 d85a .]h...W........Z +// 0x0070: c9af 261f 7816 a354 2d23 d84a 579c 4876 ..&.x..T-#.JW.Hv +// 0x0080: a391 43db 5c41 191a 92b8 dcdd 6839 eef5 ..C.\A......h9.. +// 0x0090: 728e 13e0 0679 6f47 88a0 25b9 44d8 f8e7 r....yoG..%.D... +// 0x00a0: 8afe 0bfa f811 8da5 f8a3 1f8e d23b fe12 .............;.. +// 0x00b0: d943 9327 92ad 4410 183e 688d b06d 5391 .C.'..D..>h..mS. +// 0x00c0: 695b e49f 8f1e c075 d043 afe0 1174 9db0 i[.....u.C...t.. +// 0x00d0: 06b0 f01e b85b 3c84 945e 06d0 b20f 9eaa .....[<..^...... +// 0x00e0: 123d 0ab0 2a55 309c 0ee9 3e5e db2f f377 .=..*U0...>^./.w +// 0x00f0: d7f1 9bae 373d 3316 0796 b80e dd18 5173 ....7=3.......Qs +// 0x0100: b28d 84fd 1812 d87b 42c8 5f11 4db6 b269 .......{B._.M..i +// 0x0110: 1c42 4aea d5a4 644b 6c00 f0c0 fcee 71a7 .BJ...dKl.....q. +// 0x0120: e7f0 719c a207 dc5c a6fa f005 a338 7ff0 ..q....\.....8.. +// 0x0130: 5beb 3b4d 8952 2a46 d47b a5a2 e1fb 9e76 [.;M.R*F.{.....v +// 0x0140: c815 6258 50f4 6997 bad5 b479 2d06 ebbb ..bXP.i....y-... +// 0x0150: 2cac 2ecc e4f0 1f94 ce9f 186c 61da 9681 ,..........la... +// 0x0160: 345c 4d88 efc7 037b fbe3 4402 ea06 2e5d 4\M....{..D....] +// 0x0170: 2e6e 4860 e180 3ef7 c006 0ad1 ebb9 c4ff .nH`..>......... +// 0x0180: dee2 f21c 02c2 751a ded8 ae2e 13a9 3fa2 ......u.......?. +// 0x0190: 392a 8b54 11b2 2b4e 2bf1 4780 db9f 8c10 9*.T..+N+.G..... +// 0x01a0: ac6f 61b0 7b19 423f 07e5 4628 b870 f75d .oa.{.B?..F(.p.] +// 0x01b0: 09a3 63b2 77af 5985 a0ae 51d8 243f a7c8 ..c.w.Y...Q.$?.. +// 0x01c0: ab08 7fc6 0217 c09f c412 0c45 e6aa 96bf ...........E.... +// 0x01d0: 184c 4307 1f1f c4f4 7734 da31 2088 662b .LC.....w4.1..f+ +// 0x01e0: 44c5 096f 1d1d 2dc5 ffd6 867d 9fc5 7b45 D..o..-....}..{E +// 0x01f0: f949 7dd9 38de 0d51 ac2a 32fc f50b 1bbe .I}.8..Q.*2..... +// 0x0200: 1c4b 5441 fbf3 0821 6c28 4530 5676 1d27 .KTA...!l(E0Vv.' +// 0x0210: 5087 466c 3d5b 45a6 af7f 917a 6d43 66c2 P.Fl=[E....zmCf. +// 0x0220: 036a 8bef ca60 9b13 8d29 9fda 82fa 01b1 .j...`...)...... +// 0x0230: df8f 1f83 c71d 630f 349e 508c 9f7a e3da ......c.4.P..z.. +// 0x0240: a114 3622 9df8 9926 4dac 4150 d505 7b3a ..6"...&M.AP..{: +// 0x0250: 6fed fc75 6b4f 2d60 8a89 767d 9af0 896e o..ukO-`..v}...n +// 0x0260: 907d 1ada def3 345c 0d81 283c a24f fcbb .}....4\..(<.O.. +// 0x0270: bbdd b7b3 e3bb 9f1b d966 51b7 8217 7fa0 .........fQ..... +// 0x0280: e828 d3ca a6f1 532f 164e e405 bb3b 0de3 .(....S/.N...;.. +// 0x0290: 985d 6e89 d825 ebc6 d8ba 5190 a114 c6a3 .]n..%....Q..... +// 0x02a0: 18b4 8aa7 181a 01ac cdc0 8048 ea72 a5e3 ...........H.r.. +// 0x02b0: e37a dc57 65cd b787 39e6 c39e 317b 45d8 .z.We...9...1{E. +// 0x02c0: 475c 05ba e8f8 8224 5a85 27b8 1584 8d78 G\.....$Z.'....x +// 0x02d0: 62b6 6495 ac10 338f 1122 f2ff 043e 9e2a b.d...3.."...>.* +// 0x02e0: 1058 a910 5792 6fcd 9a96 6183 6708 8f70 .X..W.o...a.g..p +// 0x02f0: edc6 a67c 64ff 50fa 520b de94 c82c c4d6 ...|d.P.R....,.. +// 0x0300: 7d8f 0fd5 2f0d 9833 7c6c be10 a4e5 dc99 }.../..3|l...... +// 0x0310: a467 ef5f b35b c11c e23c 131a 48b2 9cef .g._.[...<..H... +// 0x0320: 5a2f fece dd9e 2aea 0db9 faf3 a6ef b29d Z/....*......... +// 0x0330: e85d a410 dd6a 6806 3fc6 1694 179f cb4b .]...jh.?......K +// 0x0340: 08c4 86b2 0713 cddb b257 d56b fe82 7d82 .........W.k..}. +// 0x0350: 0d1f 6dc9 67b2 d2a1 6791 4f38 edf9 491f ..m.g...g.O8..I. +// 0x0360: 2c02 35f5 8165 ecc3 bc6a b631 3c7e 1ad4 ,.5..e...j.1<~.. +// 0x0370: 8e27 f962 f942 11b5 1b45 9bac b474 3c6e .'.b.B...E...t<n +// 0x0380: 6832 3075 be6d ac0d a8a0 7d47 a6ef 4e43 h20u.m....}G..NC +// 0x0390: 6b9a 3097 8a8b 82a3 9515 362c f7d6 a37f k.0.......6,.... +// 0x03a0: 7313 1199 a5f3 03dc bcc9 fb10 c23d eeb9 s............=.. +// 0x03b0: 78ff c8f3 0d38 9f74 ceec b7ae 63e3 3424 x....8.t....c.4$ +// 0x03c0: b783 f106 011f 666b bf2d abc8 ea10 57a1 ......fk.-....W. +// 0x03d0: 7cf2 4a3f 57ca 1386 bfba 27e5 4662 81c8 |.J?W.....'.Fb.. +// 0x03e0: 041e 1820 b3d5 c399 cd4d 222f 29f0 b994 .........M"/)... +// 0x03f0: 865a e6e2 1686 3261 b0cd caaf 07ec d0bc .Z....2a........ +// 0x0400: afb8 3cf0 51c1 6c7a 6383 6b3a ff47 9551 ..<.Q.lzc.k:.G.Q +// 0x0410: 1099 525f 355e 4684 bd34 ec12 88c9 dcc2 ..R_5^F..4...... +// 0x0420: d11c 826d f1df 37e6 f08f 6ce8 817d bdc3 ...m..7...l..}.. +// 0x0430: 20b9 a274 c645 c67d f299 fef9 287f 09ee ...t.E.}....(... +// 0x0440: ac67 6872 a126 b1d3 922c 4c2a 0ec9 b6d4 .ghr.&...,L*.... +// 0x0450: fb59 6163 d1c4 1708 8d94 bc3d be5e ae29 .Yac.......=.^.) +// 0x0460: 51ff a765 9df6 ae35 ed6b 0555 933f 3ed6 Q..e...5.k.U.?>. +// 0x0470: 259b d93e f86f 6088 0c4e 357b 5c67 7d93 %..>.o`..N5{\g}. +// 0x0480: a695 1a42 e1e1 ef91 14d7 b7b7 0ca4 2dda ...B..........-. +// 0x0490: 6ac1 771e 25c1 a578 4ca8 6fd8 de04 1c09 j.w.%..xL.o..... +// 0x04a0: df49 f179 6a58 2b45 7231 307f bc67 e5e7 .I.yjX+Er10..g.. +// 0x04b0: c5cd fec0 b021 508e 4fc5 f821 f734 90bc .....!P.O..!.4.. +// 0x04c0: c87f 14f1 2e5c d17b 1818 5b4a 6b68 0212 .....\.{..[Jkh.. +// 0x04d0: 1791 4a30 8518 99a9 b516 67e7 ed56 d1d1 ..J0......g..V.. +// 0x04e0: 239d dfda 11c5 0afe e58a b6e0 fb66 ab5c #............f.\ +// 0x04f0: f590 dcd6 457d 01d1 83f5 a9f0 cdb2 9c14 ....E}.......... +// 0x0500: ff66 f10c d428 a07b 34e3 d600 91f2 aca7 .f...(.{4....... +// 0x0510: 4e1f f3ac a96e 2aa3 ec9b 448c 748d f858 N....n*...D.t..X +// 0x0520: 131c d496 af9b f5f0 d2f5 57ac 0b64 55a1 ..........W..dU. +// 0x0530: 860e 5ad0 3e62 26b5 9e17 f51f 88c1 02e3 ..Z.>b&......... +// 0x0540: 4a38 de70 3216 6f88 5d1e f429 ee19 4121 J8.p2.o.]..)..A! +// 0x0550: f571 84ac 3789 141f 1798 90b1 8373 2499 .q..7........s$. +// 0x0560: c131 b13f f3a3 9a07 aef1 bfe8 8cd7 8c2e .1.?............ +// 0x0570: ba35 dfc5 eb07 013c 7621 6481 bdfb 6233 .5.....<v!d...b3 +// 0x0580: 22e2 0f05 7e15 0417 67e4 2632 5207 28a6 "...~...g.&2R.(. +// 0x0590: 8e88 9423 de54 5412 b53e fd8d d47a de58 ...#.TT..>...z.X +// 0x05a0: a1b2 6e08 d06d dc21 1eda 14a0 a2f7 1701 ..n..m.!........ +// 0x05b0: a5e0 dfd7 871f 595d db43 70f5 bab3 b732 ......Y].Cp....2 +// 0x05c0: 6275 da15 b203 dac7 321f 8d61 11bd 30 bu......2..a..0 +var testAnotherMalformedDNS = []byte{ + 0x00, 0x55, 0x22, 0xaf, 0xc6, 0x37, 0x00, 0x22, 0x55, 0xac, 0xde, 0xac, 0x08, 0x00, 0x45, 0x00, + 0x05, 0xc1, 0x2e, 0xea, 0x40, 0x00, 0x36, 0x11, 0xfb, 0xd1, 0x0a, 0x4d, 0x00, 0x1d, 0x0a, 0x01, + 0x00, 0x06, 0x00, 0x35, 0xa5, 0x28, 0x05, 0xad, 0x00, 0xa2, 0x34, 0xb3, 0x33, 0x13, 0x5c, 0x1f, + 0x2d, 0xc8, 0x74, 0x2e, 0xcb, 0x77, 0x2d, 0xa0, 0xbc, 0x2e, 0x56, 0x8b, 0xf7, 0x51, 0xf3, 0x22, + 0x85, 0x1d, 0xab, 0x17, 0x78, 0x10, 0x00, 0x9c, 0x1c, 0xef, 0xc6, 0xd5, 0x06, 0x05, 0x37, 0xf4, + 0x96, 0x9b, 0xc6, 0x5e, 0x48, 0x3e, 0x47, 0x06, 0xf5, 0x8b, 0xdf, 0x36, 0x47, 0xdb, 0xea, 0xe2, + 0x88, 0x5d, 0x68, 0x8a, 0xc5, 0xa5, 0x57, 0x05, 0xaa, 0xa8, 0x95, 0xeb, 0x93, 0xa4, 0xd8, 0x5a, + 0xc9, 0xaf, 0x26, 0x1f, 0x78, 0x16, 0xa3, 0x54, 0x2d, 0x23, 0xd8, 0x4a, 0x57, 0x9c, 0x48, 0x76, + 0xa3, 0x91, 0x43, 0xdb, 0x5c, 0x41, 0x19, 0x1a, 0x92, 0xb8, 0xdc, 0xdd, 0x68, 0x39, 0xee, 0xf5, + 0x72, 0x8e, 0x13, 0xe0, 0x06, 0x79, 0x6f, 0x47, 0x88, 0xa0, 0x25, 0xb9, 0x44, 0xd8, 0xf8, 0xe7, + 0x8a, 0xfe, 0x0b, 0xfa, 0xf8, 0x11, 0x8d, 0xa5, 0xf8, 0xa3, 0x1f, 0x8e, 0xd2, 0x3b, 0xfe, 0x12, + 0xd9, 0x43, 0x93, 0x27, 0x92, 0xad, 0x44, 0x10, 0x18, 0x3e, 0x68, 0x8d, 0xb0, 0x6d, 0x53, 0x91, + 0x69, 0x5b, 0xe4, 0x9f, 0x8f, 0x1e, 0xc0, 0x75, 0xd0, 0x43, 0xaf, 0xe0, 0x11, 0x74, 0x9d, 0xb0, + 0x06, 0xb0, 0xf0, 0x1e, 0xb8, 0x5b, 0x3c, 0x84, 0x94, 0x5e, 0x06, 0xd0, 0xb2, 0x0f, 0x9e, 0xaa, + 0x12, 0x3d, 0x0a, 0xb0, 0x2a, 0x55, 0x30, 0x9c, 0x0e, 0xe9, 0x3e, 0x5e, 0xdb, 0x2f, 0xf3, 0x77, + 0xd7, 0xf1, 0x9b, 0xae, 0x37, 0x3d, 0x33, 0x16, 0x07, 0x96, 0xb8, 0x0e, 0xdd, 0x18, 0x51, 0x73, + 0xb2, 0x8d, 0x84, 0xfd, 0x18, 0x12, 0xd8, 0x7b, 0x42, 0xc8, 0x5f, 0x11, 0x4d, 0xb6, 0xb2, 0x69, + 0x1c, 0x42, 0x4a, 0xea, 0xd5, 0xa4, 0x64, 0x4b, 0x6c, 0x00, 0xf0, 0xc0, 0xfc, 0xee, 0x71, 0xa7, + 0xe7, 0xf0, 0x71, 0x9c, 0xa2, 0x07, 0xdc, 0x5c, 0xa6, 0xfa, 0xf0, 0x05, 0xa3, 0x38, 0x7f, 0xf0, + 0x5b, 0xeb, 0x3b, 0x4d, 0x89, 0x52, 0x2a, 0x46, 0xd4, 0x7b, 0xa5, 0xa2, 0xe1, 0xfb, 0x9e, 0x76, + 0xc8, 0x15, 0x62, 0x58, 0x50, 0xf4, 0x69, 0x97, 0xba, 0xd5, 0xb4, 0x79, 0x2d, 0x06, 0xeb, 0xbb, + 0x2c, 0xac, 0x2e, 0xcc, 0xe4, 0xf0, 0x1f, 0x94, 0xce, 0x9f, 0x18, 0x6c, 0x61, 0xda, 0x96, 0x81, + 0x34, 0x5c, 0x4d, 0x88, 0xef, 0xc7, 0x03, 0x7b, 0xfb, 0xe3, 0x44, 0x02, 0xea, 0x06, 0x2e, 0x5d, + 0x2e, 0x6e, 0x48, 0x60, 0xe1, 0x80, 0x3e, 0xf7, 0xc0, 0x06, 0x0a, 0xd1, 0xeb, 0xb9, 0xc4, 0xff, + 0xde, 0xe2, 0xf2, 0x1c, 0x02, 0xc2, 0x75, 0x1a, 0xde, 0xd8, 0xae, 0x2e, 0x13, 0xa9, 0x3f, 0xa2, + 0x39, 0x2a, 0x8b, 0x54, 0x11, 0xb2, 0x2b, 0x4e, 0x2b, 0xf1, 0x47, 0x80, 0xdb, 0x9f, 0x8c, 0x10, + 0xac, 0x6f, 0x61, 0xb0, 0x7b, 0x19, 0x42, 0x3f, 0x07, 0xe5, 0x46, 0x28, 0xb8, 0x70, 0xf7, 0x5d, + 0x09, 0xa3, 0x63, 0xb2, 0x77, 0xaf, 0x59, 0x85, 0xa0, 0xae, 0x51, 0xd8, 0x24, 0x3f, 0xa7, 0xc8, + 0xab, 0x08, 0x7f, 0xc6, 0x02, 0x17, 0xc0, 0x9f, 0xc4, 0x12, 0x0c, 0x45, 0xe6, 0xaa, 0x96, 0xbf, + 0x18, 0x4c, 0x43, 0x07, 0x1f, 0x1f, 0xc4, 0xf4, 0x77, 0x34, 0xda, 0x31, 0x20, 0x88, 0x66, 0x2b, + 0x44, 0xc5, 0x09, 0x6f, 0x1d, 0x1d, 0x2d, 0xc5, 0xff, 0xd6, 0x86, 0x7d, 0x9f, 0xc5, 0x7b, 0x45, + 0xf9, 0x49, 0x7d, 0xd9, 0x38, 0xde, 0x0d, 0x51, 0xac, 0x2a, 0x32, 0xfc, 0xf5, 0x0b, 0x1b, 0xbe, + 0x1c, 0x4b, 0x54, 0x41, 0xfb, 0xf3, 0x08, 0x21, 0x6c, 0x28, 0x45, 0x30, 0x56, 0x76, 0x1d, 0x27, + 0x50, 0x87, 0x46, 0x6c, 0x3d, 0x5b, 0x45, 0xa6, 0xaf, 0x7f, 0x91, 0x7a, 0x6d, 0x43, 0x66, 0xc2, + 0x03, 0x6a, 0x8b, 0xef, 0xca, 0x60, 0x9b, 0x13, 0x8d, 0x29, 0x9f, 0xda, 0x82, 0xfa, 0x01, 0xb1, + 0xdf, 0x8f, 0x1f, 0x83, 0xc7, 0x1d, 0x63, 0x0f, 0x34, 0x9e, 0x50, 0x8c, 0x9f, 0x7a, 0xe3, 0xda, + 0xa1, 0x14, 0x36, 0x22, 0x9d, 0xf8, 0x99, 0x26, 0x4d, 0xac, 0x41, 0x50, 0xd5, 0x05, 0x7b, 0x3a, + 0x6f, 0xed, 0xfc, 0x75, 0x6b, 0x4f, 0x2d, 0x60, 0x8a, 0x89, 0x76, 0x7d, 0x9a, 0xf0, 0x89, 0x6e, + 0x90, 0x7d, 0x1a, 0xda, 0xde, 0xf3, 0x34, 0x5c, 0x0d, 0x81, 0x28, 0x3c, 0xa2, 0x4f, 0xfc, 0xbb, + 0xbb, 0xdd, 0xb7, 0xb3, 0xe3, 0xbb, 0x9f, 0x1b, 0xd9, 0x66, 0x51, 0xb7, 0x82, 0x17, 0x7f, 0xa0, + 0xe8, 0x28, 0xd3, 0xca, 0xa6, 0xf1, 0x53, 0x2f, 0x16, 0x4e, 0xe4, 0x05, 0xbb, 0x3b, 0x0d, 0xe3, + 0x98, 0x5d, 0x6e, 0x89, 0xd8, 0x25, 0xeb, 0xc6, 0xd8, 0xba, 0x51, 0x90, 0xa1, 0x14, 0xc6, 0xa3, + 0x18, 0xb4, 0x8a, 0xa7, 0x18, 0x1a, 0x01, 0xac, 0xcd, 0xc0, 0x80, 0x48, 0xea, 0x72, 0xa5, 0xe3, + 0xe3, 0x7a, 0xdc, 0x57, 0x65, 0xcd, 0xb7, 0x87, 0x39, 0xe6, 0xc3, 0x9e, 0x31, 0x7b, 0x45, 0xd8, + 0x47, 0x5c, 0x05, 0xba, 0xe8, 0xf8, 0x82, 0x24, 0x5a, 0x85, 0x27, 0xb8, 0x15, 0x84, 0x8d, 0x78, + 0x62, 0xb6, 0x64, 0x95, 0xac, 0x10, 0x33, 0x8f, 0x11, 0x22, 0xf2, 0xff, 0x04, 0x3e, 0x9e, 0x2a, + 0x10, 0x58, 0xa9, 0x10, 0x57, 0x92, 0x6f, 0xcd, 0x9a, 0x96, 0x61, 0x83, 0x67, 0x08, 0x8f, 0x70, + 0xed, 0xc6, 0xa6, 0x7c, 0x64, 0xff, 0x50, 0xfa, 0x52, 0x0b, 0xde, 0x94, 0xc8, 0x2c, 0xc4, 0xd6, + 0x7d, 0x8f, 0x0f, 0xd5, 0x2f, 0x0d, 0x98, 0x33, 0x7c, 0x6c, 0xbe, 0x10, 0xa4, 0xe5, 0xdc, 0x99, + 0xa4, 0x67, 0xef, 0x5f, 0xb3, 0x5b, 0xc1, 0x1c, 0xe2, 0x3c, 0x13, 0x1a, 0x48, 0xb2, 0x9c, 0xef, + 0x5a, 0x2f, 0xfe, 0xce, 0xdd, 0x9e, 0x2a, 0xea, 0x0d, 0xb9, 0xfa, 0xf3, 0xa6, 0xef, 0xb2, 0x9d, + 0xe8, 0x5d, 0xa4, 0x10, 0xdd, 0x6a, 0x68, 0x06, 0x3f, 0xc6, 0x16, 0x94, 0x17, 0x9f, 0xcb, 0x4b, + 0x08, 0xc4, 0x86, 0xb2, 0x07, 0x13, 0xcd, 0xdb, 0xb2, 0x57, 0xd5, 0x6b, 0xfe, 0x82, 0x7d, 0x82, + 0x0d, 0x1f, 0x6d, 0xc9, 0x67, 0xb2, 0xd2, 0xa1, 0x67, 0x91, 0x4f, 0x38, 0xed, 0xf9, 0x49, 0x1f, + 0x2c, 0x02, 0x35, 0xf5, 0x81, 0x65, 0xec, 0xc3, 0xbc, 0x6a, 0xb6, 0x31, 0x3c, 0x7e, 0x1a, 0xd4, + 0x8e, 0x27, 0xf9, 0x62, 0xf9, 0x42, 0x11, 0xb5, 0x1b, 0x45, 0x9b, 0xac, 0xb4, 0x74, 0x3c, 0x6e, + 0x68, 0x32, 0x30, 0x75, 0xbe, 0x6d, 0xac, 0x0d, 0xa8, 0xa0, 0x7d, 0x47, 0xa6, 0xef, 0x4e, 0x43, + 0x6b, 0x9a, 0x30, 0x97, 0x8a, 0x8b, 0x82, 0xa3, 0x95, 0x15, 0x36, 0x2c, 0xf7, 0xd6, 0xa3, 0x7f, + 0x73, 0x13, 0x11, 0x99, 0xa5, 0xf3, 0x03, 0xdc, 0xbc, 0xc9, 0xfb, 0x10, 0xc2, 0x3d, 0xee, 0xb9, + 0x78, 0xff, 0xc8, 0xf3, 0x0d, 0x38, 0x9f, 0x74, 0xce, 0xec, 0xb7, 0xae, 0x63, 0xe3, 0x34, 0x24, + 0xb7, 0x83, 0xf1, 0x06, 0x01, 0x1f, 0x66, 0x6b, 0xbf, 0x2d, 0xab, 0xc8, 0xea, 0x10, 0x57, 0xa1, + 0x7c, 0xf2, 0x4a, 0x3f, 0x57, 0xca, 0x13, 0x86, 0xbf, 0xba, 0x27, 0xe5, 0x46, 0x62, 0x81, 0xc8, + 0x04, 0x1e, 0x18, 0x20, 0xb3, 0xd5, 0xc3, 0x99, 0xcd, 0x4d, 0x22, 0x2f, 0x29, 0xf0, 0xb9, 0x94, + 0x86, 0x5a, 0xe6, 0xe2, 0x16, 0x86, 0x32, 0x61, 0xb0, 0xcd, 0xca, 0xaf, 0x07, 0xec, 0xd0, 0xbc, + 0xaf, 0xb8, 0x3c, 0xf0, 0x51, 0xc1, 0x6c, 0x7a, 0x63, 0x83, 0x6b, 0x3a, 0xff, 0x47, 0x95, 0x51, + 0x10, 0x99, 0x52, 0x5f, 0x35, 0x5e, 0x46, 0x84, 0xbd, 0x34, 0xec, 0x12, 0x88, 0xc9, 0xdc, 0xc2, + 0xd1, 0x1c, 0x82, 0x6d, 0xf1, 0xdf, 0x37, 0xe6, 0xf0, 0x8f, 0x6c, 0xe8, 0x81, 0x7d, 0xbd, 0xc3, + 0x20, 0xb9, 0xa2, 0x74, 0xc6, 0x45, 0xc6, 0x7d, 0xf2, 0x99, 0xfe, 0xf9, 0x28, 0x7f, 0x09, 0xee, + 0xac, 0x67, 0x68, 0x72, 0xa1, 0x26, 0xb1, 0xd3, 0x92, 0x2c, 0x4c, 0x2a, 0x0e, 0xc9, 0xb6, 0xd4, + 0xfb, 0x59, 0x61, 0x63, 0xd1, 0xc4, 0x17, 0x08, 0x8d, 0x94, 0xbc, 0x3d, 0xbe, 0x5e, 0xae, 0x29, + 0x51, 0xff, 0xa7, 0x65, 0x9d, 0xf6, 0xae, 0x35, 0xed, 0x6b, 0x05, 0x55, 0x93, 0x3f, 0x3e, 0xd6, + 0x25, 0x9b, 0xd9, 0x3e, 0xf8, 0x6f, 0x60, 0x88, 0x0c, 0x4e, 0x35, 0x7b, 0x5c, 0x67, 0x7d, 0x93, + 0xa6, 0x95, 0x1a, 0x42, 0xe1, 0xe1, 0xef, 0x91, 0x14, 0xd7, 0xb7, 0xb7, 0x0c, 0xa4, 0x2d, 0xda, + 0x6a, 0xc1, 0x77, 0x1e, 0x25, 0xc1, 0xa5, 0x78, 0x4c, 0xa8, 0x6f, 0xd8, 0xde, 0x04, 0x1c, 0x09, + 0xdf, 0x49, 0xf1, 0x79, 0x6a, 0x58, 0x2b, 0x45, 0x72, 0x31, 0x30, 0x7f, 0xbc, 0x67, 0xe5, 0xe7, + 0xc5, 0xcd, 0xfe, 0xc0, 0xb0, 0x21, 0x50, 0x8e, 0x4f, 0xc5, 0xf8, 0x21, 0xf7, 0x34, 0x90, 0xbc, + 0xc8, 0x7f, 0x14, 0xf1, 0x2e, 0x5c, 0xd1, 0x7b, 0x18, 0x18, 0x5b, 0x4a, 0x6b, 0x68, 0x02, 0x12, + 0x17, 0x91, 0x4a, 0x30, 0x85, 0x18, 0x99, 0xa9, 0xb5, 0x16, 0x67, 0xe7, 0xed, 0x56, 0xd1, 0xd1, + 0x23, 0x9d, 0xdf, 0xda, 0x11, 0xc5, 0x0a, 0xfe, 0xe5, 0x8a, 0xb6, 0xe0, 0xfb, 0x66, 0xab, 0x5c, + 0xf5, 0x90, 0xdc, 0xd6, 0x45, 0x7d, 0x01, 0xd1, 0x83, 0xf5, 0xa9, 0xf0, 0xcd, 0xb2, 0x9c, 0x14, + 0xff, 0x66, 0xf1, 0x0c, 0xd4, 0x28, 0xa0, 0x7b, 0x34, 0xe3, 0xd6, 0x00, 0x91, 0xf2, 0xac, 0xa7, + 0x4e, 0x1f, 0xf3, 0xac, 0xa9, 0x6e, 0x2a, 0xa3, 0xec, 0x9b, 0x44, 0x8c, 0x74, 0x8d, 0xf8, 0x58, + 0x13, 0x1c, 0xd4, 0x96, 0xaf, 0x9b, 0xf5, 0xf0, 0xd2, 0xf5, 0x57, 0xac, 0x0b, 0x64, 0x55, 0xa1, + 0x86, 0x0e, 0x5a, 0xd0, 0x3e, 0x62, 0x26, 0xb5, 0x9e, 0x17, 0xf5, 0x1f, 0x88, 0xc1, 0x02, 0xe3, + 0x4a, 0x38, 0xde, 0x70, 0x32, 0x16, 0x6f, 0x88, 0x5d, 0x1e, 0xf4, 0x29, 0xee, 0x19, 0x41, 0x21, + 0xf5, 0x71, 0x84, 0xac, 0x37, 0x89, 0x14, 0x1f, 0x17, 0x98, 0x90, 0xb1, 0x83, 0x73, 0x24, 0x99, + 0xc1, 0x31, 0xb1, 0x3f, 0xf3, 0xa3, 0x9a, 0x07, 0xae, 0xf1, 0xbf, 0xe8, 0x8c, 0xd7, 0x8c, 0x2e, + 0xba, 0x35, 0xdf, 0xc5, 0xeb, 0x07, 0x01, 0x3c, 0x76, 0x21, 0x64, 0x81, 0xbd, 0xfb, 0x62, 0x33, + 0x22, 0xe2, 0x0f, 0x05, 0x7e, 0x15, 0x04, 0x17, 0x67, 0xe4, 0x26, 0x32, 0x52, 0x07, 0x28, 0xa6, + 0x8e, 0x88, 0x94, 0x23, 0xde, 0x54, 0x54, 0x12, 0xb5, 0x3e, 0xfd, 0x8d, 0xd4, 0x7a, 0xde, 0x58, + 0xa1, 0xb2, 0x6e, 0x08, 0xd0, 0x6d, 0xdc, 0x21, 0x1e, 0xda, 0x14, 0xa0, 0xa2, 0xf7, 0x17, 0x01, + 0xa5, 0xe0, 0xdf, 0xd7, 0x87, 0x1f, 0x59, 0x5d, 0xdb, 0x43, 0x70, 0xf5, 0xba, 0xb3, 0xb7, 0x32, + 0x62, 0x75, 0xda, 0x15, 0xb2, 0x03, 0xda, 0xc7, 0x32, 0x1f, 0x8d, 0x61, 0x11, 0xbd, 0x30, +} + +func TestAnotherMalformedDNS(t *testing.T) { + p := gopacket.NewPacket(testAnotherMalformedDNS, LinkTypeEthernet, testDecodeOptions) + if errLayer := p.ErrorLayer(); errLayer == nil { + t.Error("No error layer on invalid DNS name") + } else if err := errLayer.Error(); !strings.Contains(err.Error(), "offset too high") { + t.Errorf("unexpected error message: %v", err) + } +} + +// testMalformedDNSAgain is the packet: +// 12:14:52.702061 IP 10.77.0.4.53 > 10.1.0.41.61610: 12529 updateDA [b2&3=0x5cad] [38274a] [61303q] [1718n] [14913au][|domain] +// 0x0000: 0055 22af c637 0022 55ac deac 0800 4500 .U"..7."U.....E. +// 0x0010: 0091 2dff 0000 7811 ffe2 0a4d 0004 0a01 ..-...x....M.... +// 0x0020: 0029 0035 f0aa 007d 5b53 30f1 5cad ef77 .).5...}[S0.\..w +// 0x0030: 9582 06b6 3a41 357a 8cef cdc0 a732 b800 ....:A5z.....2.. +// 0x0040: 466e 1c30 2e75 95ac c03d 1ed4 8635 2d09 Fn.0.u...=...5-. +// 0x0050: 2fee 3a82 b4f0 427e 2b6b f870 cc7f c9a1 /.:...B~+k.p.... +// 0x0060: e6f1 a761 97ec 2ff7 d248 4d95 321c 6e4e ...a../..HM.2.nN +// 0x0070: 57fa 6d3d 9ec0 fe3a 6f1e e634 4396 b494 W.m=...:o..4C... +// 0x0080: 8b7a a929 d7e1 da7c c346 ca77 4890 6bf3 .z.)...|.F.wH.k. +// 0x0090: 5ecb 7e97 c49d 3564 984f bf7c 8ac1 dd ^.~...5d.O.|... +var testMalformedDNSAgain = []byte{ + 0x00, 0x55, 0x22, 0xaf, 0xc6, 0x37, 0x00, 0x22, 0x55, 0xac, 0xde, 0xac, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x91, 0x2d, 0xff, 0x00, 0x00, 0x78, 0x11, 0xff, 0xe2, 0x0a, 0x4d, 0x00, 0x04, 0x0a, 0x01, + 0x00, 0x29, 0x00, 0x35, 0xf0, 0xaa, 0x00, 0x7d, 0x5b, 0x53, 0x30, 0xf1, 0x5c, 0xad, 0xef, 0x77, + 0x95, 0x82, 0x06, 0xb6, 0x3a, 0x41, 0x35, 0x7a, 0x8c, 0xef, 0xcd, 0xc0, 0xa7, 0x32, 0xb8, 0x00, + 0x46, 0x6e, 0x1c, 0x30, 0x2e, 0x75, 0x95, 0xac, 0xc0, 0x3d, 0x1e, 0xd4, 0x86, 0x35, 0x2d, 0x09, + 0x2f, 0xee, 0x3a, 0x82, 0xb4, 0xf0, 0x42, 0x7e, 0x2b, 0x6b, 0xf8, 0x70, 0xcc, 0x7f, 0xc9, 0xa1, + 0xe6, 0xf1, 0xa7, 0x61, 0x97, 0xec, 0x2f, 0xf7, 0xd2, 0x48, 0x4d, 0x95, 0x32, 0x1c, 0x6e, 0x4e, + 0x57, 0xfa, 0x6d, 0x3d, 0x9e, 0xc0, 0xfe, 0x3a, 0x6f, 0x1e, 0xe6, 0x34, 0x43, 0x96, 0xb4, 0x94, + 0x8b, 0x7a, 0xa9, 0x29, 0xd7, 0xe1, 0xda, 0x7c, 0xc3, 0x46, 0xca, 0x77, 0x48, 0x90, 0x6b, 0xf3, + 0x5e, 0xcb, 0x7e, 0x97, 0xc4, 0x9d, 0x35, 0x64, 0x98, 0x4f, 0xbf, 0x7c, 0x8a, 0xc1, 0xdd, +} + +func TestMalformedDNSAgain(t *testing.T) { + p := gopacket.NewPacket(testMalformedDNSAgain, LinkTypeEthernet, testDecodeOptions) + if errLayer := p.ErrorLayer(); errLayer == nil { + t.Error("No error layer on invalid DNS name") + } else if err := errLayer.Error(); !strings.Contains(err.Error(), "walked out of range") { + t.Errorf("unexpected error message: %v", err) + } +} + +// testMalformedDNSOhGodMakeItStop is the packet: +// 15:08:24.430906 IP 10.77.0.19.53 > 10.1.0.19.50635: 12397 zoneInit% [b2&3=0x7232] [47729a] [46283q] [60247n] [61718au][|domain] +// 0x0000: 0055 22af c637 0022 55ac deac 0800 4500 .U"..7."U.....E. +// 0x0010: 0079 c51c 4000 3511 6be4 0a4d 0013 0a01 .y..@.5.k..M.... +// 0x0020: 0013 0035 c5cb 0065 ef45 306d 7232 b4cb ...5...e.E0mr2.. +// 0x0030: ba71 eb57 f116 3994 e000 4626 0534 66cc .q.W..9...F&.4f. +// 0x0040: 7b32 24f2 eece bca7 20e2 9a2a e1ce e737 {2$........*...7 +// 0x0050: ac39 5fae 72ec c3ec 284f ca4a 171f 466d .9_.r...(O.J..Fm +// 0x0060: f6c6 84d7 e795 310f 26df 9b59 6db9 21cf ......1.&..Ym.!. +// 0x0070: 15cb 30a3 c4cf df23 805a ed1a 0584 4fc3 ..0....#.Z....O. +// 0x0080: 7fa3 3cb4 e04f e9 ..<..O. +var testMalformedDNSOhGodMakeItStop = []byte{ + 0x00, 0x55, 0x22, 0xaf, 0xc6, 0x37, 0x00, 0x22, 0x55, 0xac, 0xde, 0xac, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x79, 0xc5, 0x1c, 0x40, 0x00, 0x35, 0x11, 0x6b, 0xe4, 0x0a, 0x4d, 0x00, 0x13, 0x0a, 0x01, + 0x00, 0x13, 0x00, 0x35, 0xc5, 0xcb, 0x00, 0x65, 0xef, 0x45, 0x30, 0x6d, 0x72, 0x32, 0xb4, 0xcb, + 0xba, 0x71, 0xeb, 0x57, 0xf1, 0x16, 0x39, 0x94, 0xe0, 0x00, 0x46, 0x26, 0x05, 0x34, 0x66, 0xcc, + 0x7b, 0x32, 0x24, 0xf2, 0xee, 0xce, 0xbc, 0xa7, 0x20, 0xe2, 0x9a, 0x2a, 0xe1, 0xce, 0xe7, 0x37, + 0xac, 0x39, 0x5f, 0xae, 0x72, 0xec, 0xc3, 0xec, 0x28, 0x4f, 0xca, 0x4a, 0x17, 0x1f, 0x46, 0x6d, + 0xf6, 0xc6, 0x84, 0xd7, 0xe7, 0x95, 0x31, 0x0f, 0x26, 0xdf, 0x9b, 0x59, 0x6d, 0xb9, 0x21, 0xcf, + 0x15, 0xcb, 0x30, 0xa3, 0xc4, 0xcf, 0xdf, 0x23, 0x80, 0x5a, 0xed, 0x1a, 0x05, 0x84, 0x4f, 0xc3, + 0x7f, 0xa3, 0x3c, 0xb4, 0xe0, 0x4f, 0xe9, +} + +func TestMalformedDNSOhGodMakeItStop(t *testing.T) { + p := gopacket.NewPacket(testMalformedDNSOhGodMakeItStop, LinkTypeEthernet, testDecodeOptions) + if errLayer := p.ErrorLayer(); errLayer == nil { + t.Error("No error layer on invalid DNS name") + } else if err := errLayer.Error(); !strings.Contains(err.Error(), "offset pointer too high") { + t.Errorf("unexpected error message: %v", err) + } +} + +// testPacketDNSPanic7 is the packet: +// 07:56:25.174747 IP 10.77.0.11.53 > 10.1.0.67.55777: 41808*-| 3/7/0 TXT "google-site-verification=DC2uC-T8kD33lINhNzfo0bNBrw-vrCXs5BPF5BXY56g", TXT "v=spf1 include:spf-a.outlook.com include:spf-b.outlook.com ip4:157.55.9.128/25 include:spf.protection.outlook.com include:spf-a.hotmail.com include:_spf-ssg-b.microsoft.com include:_spf-ssg-c.microsoft.com ~all", TXT "google-site-verification=0iLWhIMhXEkeWwWfFU4ursTn-_OvoOjaA0Lr7Pg1sEM" (512) +// 0x0000: 0055 22af c637 0022 55ac deac 0800 4500 .U"..7."U.....E. +// 0x0010: 021c b5ca 4000 fa11 b46a 0a4d 000b 0a01 ....@....j.M.... +// 0x0020: 0043 0035 d9e1 0208 afd6 a350 8600 0001 .C.5.......P.... +// 0x0030: 0003 0007 0000 076f 7574 6c6f 6f6b 0363 .......outlook.c +// 0x0040: 6f6d 0000 1000 01c0 0c00 1000 0100 0001 om.............. +// 0x0050: 2c00 4544 676f 6f67 6c65 2d73 6974 652d ,.EDgoogle-site- +// 0x0060: 7665 7269 6669 6361 7469 6f6e 3d44 4332 verification=DC2 +// 0x0070: 7543 2d54 386b 4433 336c 494e 684e 7a66 uC-T8kD33lINhNzf +// 0x0080: 6f30 624e 4272 772d 7672 4358 7335 4250 o0bNBrw-vrCXs5BP +// 0x0090: 4635 4258 5935 3667 c00c 0010 0001 0000 F5BXY56g........ +// 0x00a0: 012c 00d3 d276 3d73 7066 3120 696e 636c .,...v=spf1.incl +// 0x00b0: 7564 653a 7370 662d 612e 6f75 746c 6f6f ude:spf-a.outloo +// 0x00c0: 6b2e 636f 6d20 696e 636c 7564 653a 7370 k.com.include:sp +// 0x00d0: 662d 622e 6f75 746c 6f6f 6b2e 636f 6d20 f-b.outlook.com. +// 0x00e0: 6970 343a 3135 372e 3535 2e39 2e31 3238 ip4:157.55.9.128 +// 0x00f0: 2f32 3520 696e 636c 7564 653a 7370 662e /25.include:spf. +// 0x0100: 7072 6f74 6563 7469 6f6e 2e6f 7574 6c6f protection.outlo +// 0x0110: 6f6b 2e63 6f6d 2069 6e63 6c75 6465 3a73 ok.com.include:s +// 0x0120: 7066 2d61 2e68 6f74 6d61 696c 2e63 6f6d pf-a.hotmail.com +// 0x0130: 2069 6e63 6c75 6465 3a5f 7370 662d 7373 .include:_spf-ss +// 0x0140: 672d 622e 6d69 6372 6f73 6f66 742e 636f g-b.microsoft.co +// 0x0150: 6d20 696e 636c 7564 653a 5f73 7066 2d73 m.include:_spf-s +// 0x0160: 7367 2d63 2e6d 6963 726f 736f 6674 2e63 sg-c.microsoft.c +// 0x0170: 6f6d 207e 616c 6cc0 0c00 1000 0100 0001 om.~all......... +// 0x0180: 2c00 4544 676f 6f67 6c65 2d73 6974 652d ,.EDgoogle-site- +// 0x0190: 7665 7269 6669 6361 7469 6f6e 3d30 694c verification=0iL +// 0x01a0: 5768 494d 6858 456b 6557 7757 6646 5534 WhIMhXEkeWwWfFU4 +// 0x01b0: 7572 7354 6e2d 5f4f 766f 4f6a 6141 304c ursTn-_OvoOjaA0L +// 0x01c0: 7237 5067 3173 454d c00c 0002 0001 0002 r7Pg1sEM........ +// 0x01d0: a300 000e 036e 7332 046d 7366 7403 6e65 .....ns2.msft.ne +// 0x01e0: 7400 c00c 0002 0001 0002 a300 0006 036e t..............n +// 0x01f0: 7334 c1ae c00c 0002 0001 0002 a300 0006 s4.............. +// 0x0200: 036e 7331 c1ae c00c 0002 0001 0002 a300 .ns1............ +// 0x0210: 0006 036e 7333 c1ae c00c 0002 0001 0002 ...ns3.......... +// 0x0220: a300 0015 046e 7331 610d .....ns1a. +var testPacketDNSPanic7 = []byte{ + 0x00, 0x55, 0x22, 0xaf, 0xc6, 0x37, 0x00, 0x22, 0x55, 0xac, 0xde, 0xac, 0x08, 0x00, 0x45, 0x00, + 0x02, 0x1c, 0xb5, 0xca, 0x40, 0x00, 0xfa, 0x11, 0xb4, 0x6a, 0x0a, 0x4d, 0x00, 0x0b, 0x0a, 0x01, + 0x00, 0x43, 0x00, 0x35, 0xd9, 0xe1, 0x02, 0x08, 0xaf, 0xd6, 0xa3, 0x50, 0x86, 0x00, 0x00, 0x01, + 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x07, 0x6f, 0x75, 0x74, 0x6c, 0x6f, 0x6f, 0x6b, 0x03, 0x63, + 0x6f, 0x6d, 0x00, 0x00, 0x10, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x01, + 0x2c, 0x00, 0x45, 0x44, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2d, 0x73, 0x69, 0x74, 0x65, 0x2d, + 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x44, 0x43, 0x32, + 0x75, 0x43, 0x2d, 0x54, 0x38, 0x6b, 0x44, 0x33, 0x33, 0x6c, 0x49, 0x4e, 0x68, 0x4e, 0x7a, 0x66, + 0x6f, 0x30, 0x62, 0x4e, 0x42, 0x72, 0x77, 0x2d, 0x76, 0x72, 0x43, 0x58, 0x73, 0x35, 0x42, 0x50, + 0x46, 0x35, 0x42, 0x58, 0x59, 0x35, 0x36, 0x67, 0xc0, 0x0c, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, + 0x01, 0x2c, 0x00, 0xd3, 0xd2, 0x76, 0x3d, 0x73, 0x70, 0x66, 0x31, 0x20, 0x69, 0x6e, 0x63, 0x6c, + 0x75, 0x64, 0x65, 0x3a, 0x73, 0x70, 0x66, 0x2d, 0x61, 0x2e, 0x6f, 0x75, 0x74, 0x6c, 0x6f, 0x6f, + 0x6b, 0x2e, 0x63, 0x6f, 0x6d, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x3a, 0x73, 0x70, + 0x66, 0x2d, 0x62, 0x2e, 0x6f, 0x75, 0x74, 0x6c, 0x6f, 0x6f, 0x6b, 0x2e, 0x63, 0x6f, 0x6d, 0x20, + 0x69, 0x70, 0x34, 0x3a, 0x31, 0x35, 0x37, 0x2e, 0x35, 0x35, 0x2e, 0x39, 0x2e, 0x31, 0x32, 0x38, + 0x2f, 0x32, 0x35, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x3a, 0x73, 0x70, 0x66, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6f, 0x75, 0x74, 0x6c, 0x6f, + 0x6f, 0x6b, 0x2e, 0x63, 0x6f, 0x6d, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x3a, 0x73, + 0x70, 0x66, 0x2d, 0x61, 0x2e, 0x68, 0x6f, 0x74, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, + 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x3a, 0x5f, 0x73, 0x70, 0x66, 0x2d, 0x73, 0x73, + 0x67, 0x2d, 0x62, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x63, 0x6f, + 0x6d, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x3a, 0x5f, 0x73, 0x70, 0x66, 0x2d, 0x73, + 0x73, 0x67, 0x2d, 0x63, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x63, + 0x6f, 0x6d, 0x20, 0x7e, 0x61, 0x6c, 0x6c, 0xc0, 0x0c, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x01, + 0x2c, 0x00, 0x45, 0x44, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2d, 0x73, 0x69, 0x74, 0x65, 0x2d, + 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x69, 0x4c, + 0x57, 0x68, 0x49, 0x4d, 0x68, 0x58, 0x45, 0x6b, 0x65, 0x57, 0x77, 0x57, 0x66, 0x46, 0x55, 0x34, + 0x75, 0x72, 0x73, 0x54, 0x6e, 0x2d, 0x5f, 0x4f, 0x76, 0x6f, 0x4f, 0x6a, 0x61, 0x41, 0x30, 0x4c, + 0x72, 0x37, 0x50, 0x67, 0x31, 0x73, 0x45, 0x4d, 0xc0, 0x0c, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, + 0xa3, 0x00, 0x00, 0x0e, 0x03, 0x6e, 0x73, 0x32, 0x04, 0x6d, 0x73, 0x66, 0x74, 0x03, 0x6e, 0x65, + 0x74, 0x00, 0xc0, 0x0c, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0xa3, 0x00, 0x00, 0x06, 0x03, 0x6e, + 0x73, 0x34, 0xc1, 0xae, 0xc0, 0x0c, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0xa3, 0x00, 0x00, 0x06, + 0x03, 0x6e, 0x73, 0x31, 0xc1, 0xae, 0xc0, 0x0c, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0xa3, 0x00, + 0x00, 0x06, 0x03, 0x6e, 0x73, 0x33, 0xc1, 0xae, 0xc0, 0x0c, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, + 0xa3, 0x00, 0x00, 0x15, 0x04, 0x6e, 0x73, 0x31, 0x61, 0x0d, +} + +func TestPacketDNSPanic7(t *testing.T) { + p := gopacket.NewPacket(testPacketDNSPanic7, LinkTypeEthernet, testDecodeOptions) + if errLayer := p.ErrorLayer(); errLayer == nil { + t.Error("No error layer on invalid DNS name") + } else if err := errLayer.Error(); !strings.Contains(err.Error(), "resource record length exceeds data") { + t.Errorf("unexpected error message: %v", err) + } +} diff --git a/vendor/github.com/google/gopacket/layers/doc.go b/vendor/github.com/google/gopacket/layers/doc.go new file mode 100644 index 0000000..3c882c3 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/doc.go @@ -0,0 +1,61 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +/* +Package layers provides decoding layers for many common protocols. + +The layers package contains decode implementations for a number of different +types of packet layers. Users of gopacket will almost always want to also use +layers to actually decode packet data into useful pieces. To see the set of +protocols that gopacket/layers is currently able to decode, +look at the set of LayerTypes defined in the Variables sections. The +layers package also defines endpoints for many of the common packet layers +that have source/destination addresses associated with them, for example IPv4/6 +(IPs) and TCP/UDP (ports). +Finally, layers contains a number of useful enumerations (IPProtocol, +EthernetType, LinkType, PPPType, etc...). Many of these implement the +gopacket.Decoder interface, so they can be passed into gopacket as decoders. + +Most common protocol layers are named using acronyms or other industry-common +names (IPv4, TCP, PPP). Some of the less common ones have their names expanded +(CiscoDiscoveryProtocol). +For certain protocols, sub-parts of the protocol are split out into their own +layers (SCTP, for example). This is done mostly in cases where portions of the +protocol may fulfill the capabilities of interesting layers (SCTPData implements +ApplicationLayer, while base SCTP implements TransportLayer), or possibly +because splitting a protocol into a few layers makes decoding easier. + +This package is meant to be used with its parent, +http://github.com/google/gopacket. + +Port Types + +Instead of using raw uint16 or uint8 values for ports, we use a different port +type for every protocol, for example TCPPort and UDPPort. This allows us to +override string behavior for each port, which we do by setting up port name +maps (TCPPortNames, UDPPortNames, etc...). Well-known ports are annotated with +their protocol names, and their String function displays these names: + + p := TCPPort(80) + fmt.Printf("Number: %d String: %v", p, p) + // Prints: "Number: 80 String: 80(http)" + +Modifying Decode Behavior + +layers links together decoding through its enumerations. For example, after +decoding layer type Ethernet, it uses Ethernet.EthernetType as its next decoder. +All enumerations that act as decoders, like EthernetType, can be modified by +users depending on their preferences. For example, if you have a spiffy new +IPv4 decoder that works way better than the one built into layers, you can do +this: + + var mySpiffyIPv4Decoder gopacket.Decoder = ... + layers.EthernetTypeMetadata[EthernetTypeIPv4].DecodeWith = mySpiffyIPv4Decoder + +This will make all future ethernet packets use your new decoder to decode IPv4 +packets, instead of the built-in decoder used by gopacket. +*/ +package layers diff --git a/vendor/github.com/google/gopacket/layers/dot11.go b/vendor/github.com/google/gopacket/layers/dot11.go new file mode 100644 index 0000000..1b53026 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/dot11.go @@ -0,0 +1,1430 @@ +// Copyright 2014 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +// See http://standards.ieee.org/findstds/standard/802.11-2012.html for info on +// all of the layers in this file. + +package layers + +import ( + "bytes" + "encoding/binary" + "fmt" + "hash/crc32" + "net" + + "github.com/google/gopacket" +) + +// Dot11Flags contains the set of 8 flags in the IEEE 802.11 frame control +// header, all in one place. +type Dot11Flags uint8 + +const ( + Dot11FlagsToDS Dot11Flags = 1 << iota + Dot11FlagsFromDS + Dot11FlagsMF + Dot11FlagsRetry + Dot11FlagsPowerManagement + Dot11FlagsMD + Dot11FlagsWEP + Dot11FlagsOrder +) + +func (d Dot11Flags) ToDS() bool { + return d&Dot11FlagsToDS != 0 +} +func (d Dot11Flags) FromDS() bool { + return d&Dot11FlagsFromDS != 0 +} +func (d Dot11Flags) MF() bool { + return d&Dot11FlagsMF != 0 +} +func (d Dot11Flags) Retry() bool { + return d&Dot11FlagsRetry != 0 +} +func (d Dot11Flags) PowerManagement() bool { + return d&Dot11FlagsPowerManagement != 0 +} +func (d Dot11Flags) MD() bool { + return d&Dot11FlagsMD != 0 +} +func (d Dot11Flags) WEP() bool { + return d&Dot11FlagsWEP != 0 +} +func (d Dot11Flags) Order() bool { + return d&Dot11FlagsOrder != 0 +} + +// String provides a human readable string for Dot11Flags. +// This string is possibly subject to change over time; if you're storing this +// persistently, you should probably store the Dot11Flags value, not its string. +func (a Dot11Flags) String() string { + var out bytes.Buffer + if a.ToDS() { + out.WriteString("TO-DS,") + } + if a.FromDS() { + out.WriteString("FROM-DS,") + } + if a.MF() { + out.WriteString("MF,") + } + if a.Retry() { + out.WriteString("Retry,") + } + if a.PowerManagement() { + out.WriteString("PowerManagement,") + } + if a.MD() { + out.WriteString("MD,") + } + if a.WEP() { + out.WriteString("WEP,") + } + if a.Order() { + out.WriteString("Order,") + } + + if length := out.Len(); length > 0 { + return string(out.Bytes()[:length-1]) // strip final comma + } + return "" +} + +type Dot11Reason uint16 + +// TODO: Verify these reasons, and append more reasons if necessary. + +const ( + Dot11ReasonReserved Dot11Reason = 1 + Dot11ReasonUnspecified Dot11Reason = 2 + Dot11ReasonAuthExpired Dot11Reason = 3 + Dot11ReasonDeauthStLeaving Dot11Reason = 4 + Dot11ReasonInactivity Dot11Reason = 5 + Dot11ReasonApFull Dot11Reason = 6 + Dot11ReasonClass2FromNonAuth Dot11Reason = 7 + Dot11ReasonClass3FromNonAss Dot11Reason = 8 + Dot11ReasonDisasStLeaving Dot11Reason = 9 + Dot11ReasonStNotAuth Dot11Reason = 10 +) + +// String provides a human readable string for Dot11Reason. +// This string is possibly subject to change over time; if you're storing this +// persistently, you should probably store the Dot11Reason value, not its string. +func (a Dot11Reason) String() string { + switch a { + case Dot11ReasonReserved: + return "Reserved" + case Dot11ReasonUnspecified: + return "Unspecified" + case Dot11ReasonAuthExpired: + return "Auth. expired" + case Dot11ReasonDeauthStLeaving: + return "Deauth. st. leaving" + case Dot11ReasonInactivity: + return "Inactivity" + case Dot11ReasonApFull: + return "Ap. full" + case Dot11ReasonClass2FromNonAuth: + return "Class2 from non auth." + case Dot11ReasonClass3FromNonAss: + return "Class3 from non ass." + case Dot11ReasonDisasStLeaving: + return "Disass st. leaving" + case Dot11ReasonStNotAuth: + return "St. not auth." + default: + return "Unknown reason" + } +} + +type Dot11Status uint16 + +const ( + Dot11StatusSuccess Dot11Status = 0 + Dot11StatusFailure Dot11Status = 1 // Unspecified failure + Dot11StatusCannotSupportAllCapabilities Dot11Status = 10 // Cannot support all requested capabilities in the Capability Information field + Dot11StatusInabilityExistsAssociation Dot11Status = 11 // Reassociation denied due to inability to confirm that association exists + Dot11StatusAssociationDenied Dot11Status = 12 // Association denied due to reason outside the scope of this standard + Dot11StatusAlgorithmUnsupported Dot11Status = 13 // Responding station does not support the specified authentication algorithm + Dot11StatusOufOfExpectedSequence Dot11Status = 14 // Received an Authentication frame with authentication transaction sequence number out of expected sequence + Dot11StatusChallengeFailure Dot11Status = 15 // Authentication rejected because of challenge failure + Dot11StatusTimeout Dot11Status = 16 // Authentication rejected due to timeout waiting for next frame in sequence + Dot11StatusAPUnableToHandle Dot11Status = 17 // Association denied because AP is unable to handle additional associated stations + Dot11StatusRateUnsupported Dot11Status = 18 // Association denied due to requesting station not supporting all of the data rates in the BSSBasicRateSet parameter +) + +// String provides a human readable string for Dot11Status. +// This string is possibly subject to change over time; if you're storing this +// persistently, you should probably store the Dot11Status value, not its string. +func (a Dot11Status) String() string { + switch a { + case Dot11StatusSuccess: + return "success" + case Dot11StatusFailure: + return "failure" + case Dot11StatusCannotSupportAllCapabilities: + return "cannot-support-all-capabilities" + case Dot11StatusInabilityExistsAssociation: + return "inability-exists-association" + case Dot11StatusAssociationDenied: + return "association-denied" + case Dot11StatusAlgorithmUnsupported: + return "algorithm-unsupported" + case Dot11StatusOufOfExpectedSequence: + return "out-of-expected-sequence" + case Dot11StatusChallengeFailure: + return "challenge-failure" + case Dot11StatusTimeout: + return "timeout" + case Dot11StatusAPUnableToHandle: + return "ap-unable-to-handle" + case Dot11StatusRateUnsupported: + return "rate-unsupported" + default: + return "unknown status" + } +} + +type Dot11AckPolicy uint8 + +const ( + Dot11AckPolicyNormal Dot11AckPolicy = 0 + Dot11AckPolicyNone Dot11AckPolicy = 1 + Dot11AckPolicyNoExplicit Dot11AckPolicy = 2 + Dot11AckPolicyBlock Dot11AckPolicy = 3 +) + +// String provides a human readable string for Dot11AckPolicy. +// This string is possibly subject to change over time; if you're storing this +// persistently, you should probably store the Dot11AckPolicy value, not its string. +func (a Dot11AckPolicy) String() string { + switch a { + case Dot11AckPolicyNormal: + return "normal-ack" + case Dot11AckPolicyNone: + return "no-ack" + case Dot11AckPolicyNoExplicit: + return "no-explicit-ack" + case Dot11AckPolicyBlock: + return "block-ack" + default: + return "unknown-ack-policy" + } +} + +type Dot11Algorithm uint16 + +const ( + Dot11AlgorithmOpen Dot11Algorithm = 0 + Dot11AlgorithmSharedKey Dot11Algorithm = 1 +) + +// String provides a human readable string for Dot11Algorithm. +// This string is possibly subject to change over time; if you're storing this +// persistently, you should probably store the Dot11Algorithm value, not its string. +func (a Dot11Algorithm) String() string { + switch a { + case Dot11AlgorithmOpen: + return "open" + case Dot11AlgorithmSharedKey: + return "shared-key" + default: + return "unknown-algorithm" + } +} + +type Dot11InformationElementID uint8 + +// TODO: Verify these element ids, and append more ids if more. + +const ( + Dot11InformationElementIDSSID Dot11InformationElementID = 0 + Dot11InformationElementIDRates Dot11InformationElementID = 1 + Dot11InformationElementIDFHSet Dot11InformationElementID = 2 + Dot11InformationElementIDDSSet Dot11InformationElementID = 3 + Dot11InformationElementIDCFSet Dot11InformationElementID = 4 + Dot11InformationElementIDTIM Dot11InformationElementID = 5 + Dot11InformationElementIDIBSSSet Dot11InformationElementID = 6 + Dot11InformationElementIDChallenge Dot11InformationElementID = 16 + Dot11InformationElementIDERPInfo Dot11InformationElementID = 42 + Dot11InformationElementIDQOSCapability Dot11InformationElementID = 46 + Dot11InformationElementIDERPInfo2 Dot11InformationElementID = 47 + Dot11InformationElementIDRSNInfo Dot11InformationElementID = 48 + Dot11InformationElementIDESRates Dot11InformationElementID = 50 + Dot11InformationElementIDVendor Dot11InformationElementID = 221 + Dot11InformationElementIDReserved Dot11InformationElementID = 68 +) + +// String provides a human readable string for Dot11InformationElementID. +// This string is possibly subject to change over time; if you're storing this +// persistently, you should probably store the Dot11InformationElementID value, +// not its string. +func (a Dot11InformationElementID) String() string { + switch a { + case Dot11InformationElementIDSSID: + return "SSID" + case Dot11InformationElementIDRates: + return "Rates" + case Dot11InformationElementIDFHSet: + return "FHset" + case Dot11InformationElementIDDSSet: + return "DSset" + case Dot11InformationElementIDCFSet: + return "CFset" + case Dot11InformationElementIDTIM: + return "TIM" + case Dot11InformationElementIDIBSSSet: + return "IBSSset" + case Dot11InformationElementIDChallenge: + return "Challenge" + case Dot11InformationElementIDERPInfo: + return "ERPinfo" + case Dot11InformationElementIDQOSCapability: + return "QOS capability" + case Dot11InformationElementIDERPInfo2: + return "ERPinfo2" + case Dot11InformationElementIDRSNInfo: + return "RSNinfo" + case Dot11InformationElementIDESRates: + return "ESrates" + case Dot11InformationElementIDVendor: + return "Vendor" + case Dot11InformationElementIDReserved: + return "Reserved" + default: + return "Unknown information element id" + } +} + +// Dot11 provides an IEEE 802.11 base packet header. +// See http://standards.ieee.org/findstds/standard/802.11-2012.html +// for excrutiating detail. +type Dot11 struct { + BaseLayer + Type Dot11Type + Proto uint8 + Flags Dot11Flags + DurationID uint16 + Address1 net.HardwareAddr + Address2 net.HardwareAddr + Address3 net.HardwareAddr + Address4 net.HardwareAddr + SequenceNumber uint16 + FragmentNumber uint16 + Checksum uint32 +} + +func decodeDot11(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11) LayerType() gopacket.LayerType { return LayerTypeDot11 } +func (m *Dot11) CanDecode() gopacket.LayerClass { return LayerTypeDot11 } +func (m *Dot11) NextLayerType() gopacket.LayerType { + if m.Flags.WEP() { + return (LayerTypeDot11WEP) + } + + return m.Type.LayerType() +} + +func (m *Dot11) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 10 { + df.SetTruncated() + return fmt.Errorf("Dot11 length %v too short, %v required", len(data), 10) + } + m.Type = Dot11Type((data[0])&0xFC) >> 2 + + m.Proto = uint8(data[0]) & 0x0003 + m.Flags = Dot11Flags(data[1]) + m.DurationID = binary.LittleEndian.Uint16(data[2:4]) + m.Address1 = net.HardwareAddr(data[4:10]) + + offset := 10 + + mainType := m.Type.MainType() + + switch mainType { + case Dot11TypeCtrl: + switch m.Type { + case Dot11TypeCtrlRTS, Dot11TypeCtrlPowersavePoll, Dot11TypeCtrlCFEnd, Dot11TypeCtrlCFEndAck: + if len(data) < offset+6 { + df.SetTruncated() + return fmt.Errorf("Dot11 length %v too short, %v required", len(data), offset+6) + } + m.Address2 = net.HardwareAddr(data[offset : offset+6]) + offset += 6 + } + case Dot11TypeMgmt, Dot11TypeData: + if len(data) < offset+14 { + df.SetTruncated() + return fmt.Errorf("Dot11 length %v too short, %v required", len(data), offset+14) + } + m.Address2 = net.HardwareAddr(data[offset : offset+6]) + offset += 6 + m.Address3 = net.HardwareAddr(data[offset : offset+6]) + offset += 6 + + m.SequenceNumber = (binary.LittleEndian.Uint16(data[offset:offset+2]) & 0xFFF0) >> 4 + m.FragmentNumber = (binary.LittleEndian.Uint16(data[offset:offset+2]) & 0x000F) + offset += 2 + } + + if mainType == Dot11TypeData && m.Flags.FromDS() && m.Flags.ToDS() { + if len(data) < offset+6 { + df.SetTruncated() + return fmt.Errorf("Dot11 length %v too short, %v required", len(data), offset+6) + } + m.Address4 = net.HardwareAddr(data[offset : offset+6]) + offset += 6 + } + + m.BaseLayer = BaseLayer{Contents: data[0:offset], Payload: data[offset : len(data)-4]} + m.Checksum = binary.LittleEndian.Uint32(data[len(data)-4 : len(data)]) + return nil +} + +func (m *Dot11) ChecksumValid() bool { + // only for CTRL and MGMT frames + h := crc32.NewIEEE() + h.Write(m.Contents) + h.Write(m.Payload) + return m.Checksum == h.Sum32() +} + +func (m Dot11) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + buf, err := b.PrependBytes(24) + + if err != nil { + return err + } + + buf[0] = (uint8(m.Type) << 2) | m.Proto + buf[1] = uint8(m.Flags) + + binary.LittleEndian.PutUint16(buf[2:4], m.DurationID) + + copy(buf[4:10], m.Address1) + + offset := 10 + + switch m.Type.MainType() { + case Dot11TypeCtrl: + switch m.Type { + case Dot11TypeCtrlRTS, Dot11TypeCtrlPowersavePoll, Dot11TypeCtrlCFEnd, Dot11TypeCtrlCFEndAck: + copy(buf[offset:offset+6], m.Address2) + offset += 6 + } + case Dot11TypeMgmt, Dot11TypeData: + copy(buf[offset:offset+6], m.Address2) + offset += 6 + copy(buf[offset:offset+6], m.Address3) + offset += 6 + + binary.LittleEndian.PutUint16(buf[offset:offset+2], (m.SequenceNumber<<4)|m.FragmentNumber) + offset += 2 + } + + if m.Type.MainType() == Dot11TypeData && m.Flags.FromDS() && m.Flags.ToDS() { + copy(buf[offset:offset+6], m.Address4) + offset += 6 + } + + return nil +} + +// Dot11Mgmt is a base for all IEEE 802.11 management layers. +type Dot11Mgmt struct { + BaseLayer +} + +func (m *Dot11Mgmt) NextLayerType() gopacket.LayerType { return gopacket.LayerTypePayload } +func (m *Dot11Mgmt) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + m.Contents = data + return nil +} + +// Dot11Ctrl is a base for all IEEE 802.11 control layers. +type Dot11Ctrl struct { + BaseLayer +} + +func (m *Dot11Ctrl) NextLayerType() gopacket.LayerType { return gopacket.LayerTypePayload } + +func (m *Dot11Ctrl) LayerType() gopacket.LayerType { return LayerTypeDot11Ctrl } +func (m *Dot11Ctrl) CanDecode() gopacket.LayerClass { return LayerTypeDot11Ctrl } +func (m *Dot11Ctrl) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + m.Contents = data + return nil +} + +func decodeDot11Ctrl(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11Ctrl{} + return decodingLayerDecoder(d, data, p) +} + +// Dot11WEP contains WEP encrpted IEEE 802.11 data. +type Dot11WEP struct { + BaseLayer +} + +func (m *Dot11WEP) NextLayerType() gopacket.LayerType { return LayerTypeLLC } + +func (m *Dot11WEP) LayerType() gopacket.LayerType { return LayerTypeDot11WEP } +func (m *Dot11WEP) CanDecode() gopacket.LayerClass { return LayerTypeDot11WEP } +func (m *Dot11WEP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + m.Contents = data + return nil +} + +func decodeDot11WEP(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11WEP{} + return decodingLayerDecoder(d, data, p) +} + +// Dot11Data is a base for all IEEE 802.11 data layers. +type Dot11Data struct { + BaseLayer +} + +func (m *Dot11Data) NextLayerType() gopacket.LayerType { return LayerTypeLLC } + +func (m *Dot11Data) LayerType() gopacket.LayerType { return LayerTypeDot11Data } +func (m *Dot11Data) CanDecode() gopacket.LayerClass { return LayerTypeDot11Data } +func (m *Dot11Data) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + m.Payload = data + return nil +} + +func decodeDot11Data(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11Data{} + return decodingLayerDecoder(d, data, p) +} + +type Dot11DataCFAck struct { + Dot11Data +} + +func decodeDot11DataCFAck(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataCFAck{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataCFAck) LayerType() gopacket.LayerType { return LayerTypeDot11DataCFAck } +func (m *Dot11DataCFAck) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataCFAck } +func (m *Dot11DataCFAck) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Data.DecodeFromBytes(data, df) +} + +type Dot11DataCFPoll struct { + Dot11Data +} + +func decodeDot11DataCFPoll(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataCFPoll{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataCFPoll) LayerType() gopacket.LayerType { return LayerTypeDot11DataCFPoll } +func (m *Dot11DataCFPoll) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataCFPoll } +func (m *Dot11DataCFPoll) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Data.DecodeFromBytes(data, df) +} + +type Dot11DataCFAckPoll struct { + Dot11Data +} + +func decodeDot11DataCFAckPoll(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataCFAckPoll{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataCFAckPoll) LayerType() gopacket.LayerType { return LayerTypeDot11DataCFAckPoll } +func (m *Dot11DataCFAckPoll) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataCFAckPoll } +func (m *Dot11DataCFAckPoll) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Data.DecodeFromBytes(data, df) +} + +type Dot11DataNull struct { + Dot11Data +} + +func decodeDot11DataNull(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataNull{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataNull) LayerType() gopacket.LayerType { return LayerTypeDot11DataNull } +func (m *Dot11DataNull) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataNull } +func (m *Dot11DataNull) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Data.DecodeFromBytes(data, df) +} + +type Dot11DataCFAckNoData struct { + Dot11Data +} + +func decodeDot11DataCFAckNoData(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataCFAckNoData{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataCFAckNoData) LayerType() gopacket.LayerType { return LayerTypeDot11DataCFAckNoData } +func (m *Dot11DataCFAckNoData) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataCFAckNoData } +func (m *Dot11DataCFAckNoData) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Data.DecodeFromBytes(data, df) +} + +type Dot11DataCFPollNoData struct { + Dot11Data +} + +func decodeDot11DataCFPollNoData(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataCFPollNoData{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataCFPollNoData) LayerType() gopacket.LayerType { return LayerTypeDot11DataCFPollNoData } +func (m *Dot11DataCFPollNoData) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataCFPollNoData } +func (m *Dot11DataCFPollNoData) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Data.DecodeFromBytes(data, df) +} + +type Dot11DataCFAckPollNoData struct { + Dot11Data +} + +func decodeDot11DataCFAckPollNoData(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataCFAckPollNoData{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataCFAckPollNoData) LayerType() gopacket.LayerType { + return LayerTypeDot11DataCFAckPollNoData +} +func (m *Dot11DataCFAckPollNoData) CanDecode() gopacket.LayerClass { + return LayerTypeDot11DataCFAckPollNoData +} +func (m *Dot11DataCFAckPollNoData) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Data.DecodeFromBytes(data, df) +} + +type Dot11DataQOS struct { + Dot11Ctrl + TID uint8 /* Traffic IDentifier */ + EOSP bool /* End of service period */ + AckPolicy Dot11AckPolicy + TXOP uint8 +} + +func (m *Dot11DataQOS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 4 { + df.SetTruncated() + return fmt.Errorf("Dot11DataQOS length %v too short, %v required", len(data), 4) + } + m.TID = (uint8(data[0]) & 0x0F) + m.EOSP = (uint8(data[0]) & 0x10) == 0x10 + m.AckPolicy = Dot11AckPolicy((uint8(data[0]) & 0x60) >> 5) + m.TXOP = uint8(data[1]) + // TODO: Mesh Control bytes 2:4 + m.BaseLayer = BaseLayer{Contents: data[0:4], Payload: data[4:]} + return nil +} + +type Dot11DataQOSData struct { + Dot11DataQOS +} + +func decodeDot11DataQOSData(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataQOSData{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataQOSData) LayerType() gopacket.LayerType { return LayerTypeDot11DataQOSData } +func (m *Dot11DataQOSData) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataQOSData } + +func (m *Dot11DataQOSData) NextLayerType() gopacket.LayerType { + return LayerTypeDot11Data +} + +type Dot11DataQOSDataCFAck struct { + Dot11DataQOS +} + +func decodeDot11DataQOSDataCFAck(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataQOSDataCFAck{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataQOSDataCFAck) LayerType() gopacket.LayerType { return LayerTypeDot11DataQOSDataCFAck } +func (m *Dot11DataQOSDataCFAck) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataQOSDataCFAck } +func (m *Dot11DataQOSDataCFAck) NextLayerType() gopacket.LayerType { return LayerTypeDot11DataCFAck } + +type Dot11DataQOSDataCFPoll struct { + Dot11DataQOS +} + +func decodeDot11DataQOSDataCFPoll(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataQOSDataCFPoll{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataQOSDataCFPoll) LayerType() gopacket.LayerType { + return LayerTypeDot11DataQOSDataCFPoll +} +func (m *Dot11DataQOSDataCFPoll) CanDecode() gopacket.LayerClass { + return LayerTypeDot11DataQOSDataCFPoll +} +func (m *Dot11DataQOSDataCFPoll) NextLayerType() gopacket.LayerType { return LayerTypeDot11DataCFPoll } + +type Dot11DataQOSDataCFAckPoll struct { + Dot11DataQOS +} + +func decodeDot11DataQOSDataCFAckPoll(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataQOSDataCFAckPoll{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataQOSDataCFAckPoll) LayerType() gopacket.LayerType { + return LayerTypeDot11DataQOSDataCFAckPoll +} +func (m *Dot11DataQOSDataCFAckPoll) CanDecode() gopacket.LayerClass { + return LayerTypeDot11DataQOSDataCFAckPoll +} +func (m *Dot11DataQOSDataCFAckPoll) NextLayerType() gopacket.LayerType { + return LayerTypeDot11DataCFAckPoll +} + +type Dot11DataQOSNull struct { + Dot11DataQOS +} + +func decodeDot11DataQOSNull(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataQOSNull{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataQOSNull) LayerType() gopacket.LayerType { return LayerTypeDot11DataQOSNull } +func (m *Dot11DataQOSNull) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataQOSNull } +func (m *Dot11DataQOSNull) NextLayerType() gopacket.LayerType { return LayerTypeDot11DataNull } + +type Dot11DataQOSCFPollNoData struct { + Dot11DataQOS +} + +func decodeDot11DataQOSCFPollNoData(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataQOSCFPollNoData{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataQOSCFPollNoData) LayerType() gopacket.LayerType { + return LayerTypeDot11DataQOSCFPollNoData +} +func (m *Dot11DataQOSCFPollNoData) CanDecode() gopacket.LayerClass { + return LayerTypeDot11DataQOSCFPollNoData +} +func (m *Dot11DataQOSCFPollNoData) NextLayerType() gopacket.LayerType { + return LayerTypeDot11DataCFPollNoData +} + +type Dot11DataQOSCFAckPollNoData struct { + Dot11DataQOS +} + +func decodeDot11DataQOSCFAckPollNoData(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataQOSCFAckPollNoData{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataQOSCFAckPollNoData) LayerType() gopacket.LayerType { + return LayerTypeDot11DataQOSCFAckPollNoData +} +func (m *Dot11DataQOSCFAckPollNoData) CanDecode() gopacket.LayerClass { + return LayerTypeDot11DataQOSCFAckPollNoData +} +func (m *Dot11DataQOSCFAckPollNoData) NextLayerType() gopacket.LayerType { + return LayerTypeDot11DataCFAckPollNoData +} + +type Dot11InformationElement struct { + BaseLayer + ID Dot11InformationElementID + Length uint8 + OUI []byte + Info []byte +} + +func (m *Dot11InformationElement) LayerType() gopacket.LayerType { + return LayerTypeDot11InformationElement +} +func (m *Dot11InformationElement) CanDecode() gopacket.LayerClass { + return LayerTypeDot11InformationElement +} + +func (m *Dot11InformationElement) NextLayerType() gopacket.LayerType { + return LayerTypeDot11InformationElement +} + +func (m *Dot11InformationElement) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 2 { + df.SetTruncated() + return fmt.Errorf("Dot11InformationElement length %v too short, %v required", len(data), 2) + } + m.ID = Dot11InformationElementID(data[0]) + m.Length = data[1] + offset := int(2) + + if len(data) < offset+int(m.Length) { + df.SetTruncated() + return fmt.Errorf("Dot11InformationElement length %v too short, %v required", len(data), offset+int(m.Length)) + } + if m.ID == 221 { + // Vendor extension + m.OUI = data[offset : offset+4] + m.Info = data[offset+4 : offset+int(m.Length)] + } else { + m.Info = data[offset : offset+int(m.Length)] + } + + offset += int(m.Length) + + m.BaseLayer = BaseLayer{Contents: data[:offset], Payload: data[offset:]} + return nil +} + +func (d *Dot11InformationElement) String() string { + if d.ID == 0 { + return fmt.Sprintf("802.11 Information Element (SSID: %v)", string(d.Info)) + } else if d.ID == 1 { + rates := "" + for i := 0; i < len(d.Info); i++ { + if d.Info[i]&0x80 == 0 { + rates += fmt.Sprintf("%.1f ", float32(d.Info[i])*0.5) + } else { + rates += fmt.Sprintf("%.1f* ", float32(d.Info[i]&0x7F)*0.5) + } + } + return fmt.Sprintf("802.11 Information Element (Rates: %s Mbit)", rates) + } else if d.ID == 221 { + return fmt.Sprintf("802.11 Information Element (Vendor: ID: %v, Length: %v, OUI: %X, Info: %X)", d.ID, d.Length, d.OUI, d.Info) + } else { + return fmt.Sprintf("802.11 Information Element (ID: %v, Length: %v, Info: %X)", d.ID, d.Length, d.Info) + } +} + +func (m Dot11InformationElement) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + length := len(m.Info) + len(m.OUI) + if buf, err := b.PrependBytes(2 + length); err != nil { + return err + } else { + buf[0] = uint8(m.ID) + buf[1] = uint8(length) + copy(buf[2:], m.OUI) + copy(buf[2+len(m.OUI):], m.Info) + } + return nil +} + +func decodeDot11InformationElement(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11InformationElement{} + return decodingLayerDecoder(d, data, p) +} + +type Dot11CtrlCTS struct { + Dot11Ctrl +} + +func decodeDot11CtrlCTS(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11CtrlCTS{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11CtrlCTS) LayerType() gopacket.LayerType { + return LayerTypeDot11CtrlCTS +} +func (m *Dot11CtrlCTS) CanDecode() gopacket.LayerClass { + return LayerTypeDot11CtrlCTS +} +func (m *Dot11CtrlCTS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Ctrl.DecodeFromBytes(data, df) +} + +type Dot11CtrlRTS struct { + Dot11Ctrl +} + +func decodeDot11CtrlRTS(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11CtrlRTS{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11CtrlRTS) LayerType() gopacket.LayerType { + return LayerTypeDot11CtrlRTS +} +func (m *Dot11CtrlRTS) CanDecode() gopacket.LayerClass { + return LayerTypeDot11CtrlRTS +} +func (m *Dot11CtrlRTS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Ctrl.DecodeFromBytes(data, df) +} + +type Dot11CtrlBlockAckReq struct { + Dot11Ctrl +} + +func decodeDot11CtrlBlockAckReq(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11CtrlBlockAckReq{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11CtrlBlockAckReq) LayerType() gopacket.LayerType { + return LayerTypeDot11CtrlBlockAckReq +} +func (m *Dot11CtrlBlockAckReq) CanDecode() gopacket.LayerClass { + return LayerTypeDot11CtrlBlockAckReq +} +func (m *Dot11CtrlBlockAckReq) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Ctrl.DecodeFromBytes(data, df) +} + +type Dot11CtrlBlockAck struct { + Dot11Ctrl +} + +func decodeDot11CtrlBlockAck(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11CtrlBlockAck{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11CtrlBlockAck) LayerType() gopacket.LayerType { return LayerTypeDot11CtrlBlockAck } +func (m *Dot11CtrlBlockAck) CanDecode() gopacket.LayerClass { return LayerTypeDot11CtrlBlockAck } +func (m *Dot11CtrlBlockAck) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Ctrl.DecodeFromBytes(data, df) +} + +type Dot11CtrlPowersavePoll struct { + Dot11Ctrl +} + +func decodeDot11CtrlPowersavePoll(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11CtrlPowersavePoll{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11CtrlPowersavePoll) LayerType() gopacket.LayerType { + return LayerTypeDot11CtrlPowersavePoll +} +func (m *Dot11CtrlPowersavePoll) CanDecode() gopacket.LayerClass { + return LayerTypeDot11CtrlPowersavePoll +} +func (m *Dot11CtrlPowersavePoll) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Ctrl.DecodeFromBytes(data, df) +} + +type Dot11CtrlAck struct { + Dot11Ctrl +} + +func decodeDot11CtrlAck(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11CtrlAck{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11CtrlAck) LayerType() gopacket.LayerType { return LayerTypeDot11CtrlAck } +func (m *Dot11CtrlAck) CanDecode() gopacket.LayerClass { return LayerTypeDot11CtrlAck } +func (m *Dot11CtrlAck) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Ctrl.DecodeFromBytes(data, df) +} + +type Dot11CtrlCFEnd struct { + Dot11Ctrl +} + +func decodeDot11CtrlCFEnd(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11CtrlCFEnd{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11CtrlCFEnd) LayerType() gopacket.LayerType { + return LayerTypeDot11CtrlCFEnd +} +func (m *Dot11CtrlCFEnd) CanDecode() gopacket.LayerClass { + return LayerTypeDot11CtrlCFEnd +} +func (m *Dot11CtrlCFEnd) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Ctrl.DecodeFromBytes(data, df) +} + +type Dot11CtrlCFEndAck struct { + Dot11Ctrl +} + +func decodeDot11CtrlCFEndAck(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11CtrlCFEndAck{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11CtrlCFEndAck) LayerType() gopacket.LayerType { + return LayerTypeDot11CtrlCFEndAck +} +func (m *Dot11CtrlCFEndAck) CanDecode() gopacket.LayerClass { + return LayerTypeDot11CtrlCFEndAck +} +func (m *Dot11CtrlCFEndAck) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Ctrl.DecodeFromBytes(data, df) +} + +type Dot11MgmtAssociationReq struct { + Dot11Mgmt + CapabilityInfo uint16 + ListenInterval uint16 +} + +func decodeDot11MgmtAssociationReq(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtAssociationReq{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtAssociationReq) LayerType() gopacket.LayerType { + return LayerTypeDot11MgmtAssociationReq +} +func (m *Dot11MgmtAssociationReq) CanDecode() gopacket.LayerClass { + return LayerTypeDot11MgmtAssociationReq +} +func (m *Dot11MgmtAssociationReq) NextLayerType() gopacket.LayerType { + return LayerTypeDot11InformationElement +} +func (m *Dot11MgmtAssociationReq) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 4 { + df.SetTruncated() + return fmt.Errorf("Dot11MgmtAssociationReq length %v too short, %v required", len(data), 4) + } + m.CapabilityInfo = binary.LittleEndian.Uint16(data[0:2]) + m.ListenInterval = binary.LittleEndian.Uint16(data[2:4]) + m.Payload = data[4:] + return m.Dot11Mgmt.DecodeFromBytes(data, df) +} + +func (m Dot11MgmtAssociationReq) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + buf, err := b.PrependBytes(4) + + if err != nil { + return err + } + + binary.LittleEndian.PutUint16(buf[0:2], m.CapabilityInfo) + binary.LittleEndian.PutUint16(buf[2:4], m.ListenInterval) + + return nil +} + +type Dot11MgmtAssociationResp struct { + Dot11Mgmt + CapabilityInfo uint16 + Status Dot11Status + AID uint16 +} + +func decodeDot11MgmtAssociationResp(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtAssociationResp{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtAssociationResp) CanDecode() gopacket.LayerClass { + return LayerTypeDot11MgmtAssociationResp +} +func (m *Dot11MgmtAssociationResp) LayerType() gopacket.LayerType { + return LayerTypeDot11MgmtAssociationResp +} +func (m *Dot11MgmtAssociationResp) NextLayerType() gopacket.LayerType { + return LayerTypeDot11InformationElement +} +func (m *Dot11MgmtAssociationResp) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 6 { + df.SetTruncated() + return fmt.Errorf("Dot11MgmtAssociationResp length %v too short, %v required", len(data), 6) + } + m.CapabilityInfo = binary.LittleEndian.Uint16(data[0:2]) + m.Status = Dot11Status(binary.LittleEndian.Uint16(data[2:4])) + m.AID = binary.LittleEndian.Uint16(data[4:6]) + m.Payload = data[6:] + return m.Dot11Mgmt.DecodeFromBytes(data, df) +} + +func (m Dot11MgmtAssociationResp) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + buf, err := b.PrependBytes(6) + + if err != nil { + return err + } + + binary.LittleEndian.PutUint16(buf[0:2], m.CapabilityInfo) + binary.LittleEndian.PutUint16(buf[2:4], uint16(m.Status)) + binary.LittleEndian.PutUint16(buf[4:6], m.AID) + + return nil +} + +type Dot11MgmtReassociationReq struct { + Dot11Mgmt + CapabilityInfo uint16 + ListenInterval uint16 + CurrentApAddress net.HardwareAddr +} + +func decodeDot11MgmtReassociationReq(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtReassociationReq{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtReassociationReq) LayerType() gopacket.LayerType { + return LayerTypeDot11MgmtReassociationReq +} +func (m *Dot11MgmtReassociationReq) CanDecode() gopacket.LayerClass { + return LayerTypeDot11MgmtReassociationReq +} +func (m *Dot11MgmtReassociationReq) NextLayerType() gopacket.LayerType { + return LayerTypeDot11InformationElement +} +func (m *Dot11MgmtReassociationReq) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 10 { + df.SetTruncated() + return fmt.Errorf("Dot11MgmtReassociationReq length %v too short, %v required", len(data), 10) + } + m.CapabilityInfo = binary.LittleEndian.Uint16(data[0:2]) + m.ListenInterval = binary.LittleEndian.Uint16(data[2:4]) + m.CurrentApAddress = net.HardwareAddr(data[4:10]) + m.Payload = data[10:] + return m.Dot11Mgmt.DecodeFromBytes(data, df) +} + +func (m Dot11MgmtReassociationReq) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + buf, err := b.PrependBytes(10) + + if err != nil { + return err + } + + binary.LittleEndian.PutUint16(buf[0:2], m.CapabilityInfo) + binary.LittleEndian.PutUint16(buf[2:4], m.ListenInterval) + + copy(buf[4:10], m.CurrentApAddress) + + return nil +} + +type Dot11MgmtReassociationResp struct { + Dot11Mgmt +} + +func decodeDot11MgmtReassociationResp(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtReassociationResp{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtReassociationResp) LayerType() gopacket.LayerType { + return LayerTypeDot11MgmtReassociationResp +} +func (m *Dot11MgmtReassociationResp) CanDecode() gopacket.LayerClass { + return LayerTypeDot11MgmtReassociationResp +} +func (m *Dot11MgmtReassociationResp) NextLayerType() gopacket.LayerType { + return LayerTypeDot11InformationElement +} + +type Dot11MgmtProbeReq struct { + Dot11Mgmt +} + +func decodeDot11MgmtProbeReq(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtProbeReq{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtProbeReq) LayerType() gopacket.LayerType { return LayerTypeDot11MgmtProbeReq } +func (m *Dot11MgmtProbeReq) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtProbeReq } +func (m *Dot11MgmtProbeReq) NextLayerType() gopacket.LayerType { + return LayerTypeDot11InformationElement +} + +type Dot11MgmtProbeResp struct { + Dot11Mgmt + Timestamp uint64 + Interval uint16 + Flags uint16 +} + +func decodeDot11MgmtProbeResp(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtProbeResp{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtProbeResp) LayerType() gopacket.LayerType { return LayerTypeDot11MgmtProbeResp } +func (m *Dot11MgmtProbeResp) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtProbeResp } +func (m *Dot11MgmtProbeResp) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 12 { + df.SetTruncated() + + return fmt.Errorf("Dot11MgmtProbeResp length %v too short, %v required", len(data), 12) + } + + m.Timestamp = binary.LittleEndian.Uint64(data[0:8]) + m.Interval = binary.LittleEndian.Uint16(data[8:10]) + m.Flags = binary.LittleEndian.Uint16(data[10:12]) + m.Payload = data[12:] + + return m.Dot11Mgmt.DecodeFromBytes(data, df) +} + +func (m *Dot11MgmtProbeResp) NextLayerType() gopacket.LayerType { + return LayerTypeDot11InformationElement +} + +func (m Dot11MgmtProbeResp) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + buf, err := b.PrependBytes(12) + + if err != nil { + return err + } + + binary.LittleEndian.PutUint64(buf[0:8], m.Timestamp) + binary.LittleEndian.PutUint16(buf[8:10], m.Interval) + binary.LittleEndian.PutUint16(buf[10:12], m.Flags) + + return nil +} + +type Dot11MgmtMeasurementPilot struct { + Dot11Mgmt +} + +func decodeDot11MgmtMeasurementPilot(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtMeasurementPilot{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtMeasurementPilot) LayerType() gopacket.LayerType { + return LayerTypeDot11MgmtMeasurementPilot +} +func (m *Dot11MgmtMeasurementPilot) CanDecode() gopacket.LayerClass { + return LayerTypeDot11MgmtMeasurementPilot +} + +type Dot11MgmtBeacon struct { + Dot11Mgmt + Timestamp uint64 + Interval uint16 + Flags uint16 +} + +func decodeDot11MgmtBeacon(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtBeacon{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtBeacon) LayerType() gopacket.LayerType { return LayerTypeDot11MgmtBeacon } +func (m *Dot11MgmtBeacon) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtBeacon } +func (m *Dot11MgmtBeacon) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 12 { + df.SetTruncated() + return fmt.Errorf("Dot11MgmtBeacon length %v too short, %v required", len(data), 12) + } + m.Timestamp = binary.LittleEndian.Uint64(data[0:8]) + m.Interval = binary.LittleEndian.Uint16(data[8:10]) + m.Flags = binary.LittleEndian.Uint16(data[10:12]) + m.Payload = data[12:] + return m.Dot11Mgmt.DecodeFromBytes(data, df) +} + +func (m *Dot11MgmtBeacon) NextLayerType() gopacket.LayerType { return LayerTypeDot11InformationElement } + +func (m Dot11MgmtBeacon) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + buf, err := b.PrependBytes(12) + + if err != nil { + return err + } + + binary.LittleEndian.PutUint64(buf[0:8], m.Timestamp) + binary.LittleEndian.PutUint16(buf[8:10], m.Interval) + binary.LittleEndian.PutUint16(buf[10:12], m.Flags) + + return nil +} + +type Dot11MgmtATIM struct { + Dot11Mgmt +} + +func decodeDot11MgmtATIM(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtATIM{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtATIM) LayerType() gopacket.LayerType { return LayerTypeDot11MgmtATIM } +func (m *Dot11MgmtATIM) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtATIM } + +type Dot11MgmtDisassociation struct { + Dot11Mgmt + Reason Dot11Reason +} + +func decodeDot11MgmtDisassociation(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtDisassociation{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtDisassociation) LayerType() gopacket.LayerType { + return LayerTypeDot11MgmtDisassociation +} +func (m *Dot11MgmtDisassociation) CanDecode() gopacket.LayerClass { + return LayerTypeDot11MgmtDisassociation +} +func (m *Dot11MgmtDisassociation) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 2 { + df.SetTruncated() + return fmt.Errorf("Dot11MgmtDisassociation length %v too short, %v required", len(data), 2) + } + m.Reason = Dot11Reason(binary.LittleEndian.Uint16(data[0:2])) + return m.Dot11Mgmt.DecodeFromBytes(data, df) +} + +func (m Dot11MgmtDisassociation) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + buf, err := b.PrependBytes(2) + + if err != nil { + return err + } + + binary.LittleEndian.PutUint16(buf[0:2], uint16(m.Reason)) + + return nil +} + +type Dot11MgmtAuthentication struct { + Dot11Mgmt + Algorithm Dot11Algorithm + Sequence uint16 + Status Dot11Status +} + +func decodeDot11MgmtAuthentication(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtAuthentication{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtAuthentication) LayerType() gopacket.LayerType { + return LayerTypeDot11MgmtAuthentication +} +func (m *Dot11MgmtAuthentication) CanDecode() gopacket.LayerClass { + return LayerTypeDot11MgmtAuthentication +} +func (m *Dot11MgmtAuthentication) NextLayerType() gopacket.LayerType { + return LayerTypeDot11InformationElement +} +func (m *Dot11MgmtAuthentication) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 6 { + df.SetTruncated() + return fmt.Errorf("Dot11MgmtAuthentication length %v too short, %v required", len(data), 6) + } + m.Algorithm = Dot11Algorithm(binary.LittleEndian.Uint16(data[0:2])) + m.Sequence = binary.LittleEndian.Uint16(data[2:4]) + m.Status = Dot11Status(binary.LittleEndian.Uint16(data[4:6])) + m.Payload = data[6:] + return m.Dot11Mgmt.DecodeFromBytes(data, df) +} + +func (m Dot11MgmtAuthentication) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + buf, err := b.PrependBytes(6) + + if err != nil { + return err + } + + binary.LittleEndian.PutUint16(buf[0:2], uint16(m.Algorithm)) + binary.LittleEndian.PutUint16(buf[2:4], m.Sequence) + binary.LittleEndian.PutUint16(buf[4:6], uint16(m.Status)) + + return nil +} + +type Dot11MgmtDeauthentication struct { + Dot11Mgmt + Reason Dot11Reason +} + +func decodeDot11MgmtDeauthentication(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtDeauthentication{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtDeauthentication) LayerType() gopacket.LayerType { + return LayerTypeDot11MgmtDeauthentication +} +func (m *Dot11MgmtDeauthentication) CanDecode() gopacket.LayerClass { + return LayerTypeDot11MgmtDeauthentication +} +func (m *Dot11MgmtDeauthentication) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 2 { + df.SetTruncated() + return fmt.Errorf("Dot11MgmtDeauthentication length %v too short, %v required", len(data), 2) + } + m.Reason = Dot11Reason(binary.LittleEndian.Uint16(data[0:2])) + return m.Dot11Mgmt.DecodeFromBytes(data, df) +} + +func (m Dot11MgmtDeauthentication) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + buf, err := b.PrependBytes(2) + + if err != nil { + return err + } + + binary.LittleEndian.PutUint16(buf[0:2], uint16(m.Reason)) + + return nil +} + +type Dot11MgmtAction struct { + Dot11Mgmt +} + +func decodeDot11MgmtAction(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtAction{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtAction) LayerType() gopacket.LayerType { return LayerTypeDot11MgmtAction } +func (m *Dot11MgmtAction) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtAction } + +type Dot11MgmtActionNoAck struct { + Dot11Mgmt +} + +func decodeDot11MgmtActionNoAck(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtActionNoAck{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtActionNoAck) LayerType() gopacket.LayerType { return LayerTypeDot11MgmtActionNoAck } +func (m *Dot11MgmtActionNoAck) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtActionNoAck } + +type Dot11MgmtArubaWLAN struct { + Dot11Mgmt +} + +func decodeDot11MgmtArubaWLAN(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtArubaWLAN{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtArubaWLAN) LayerType() gopacket.LayerType { return LayerTypeDot11MgmtArubaWLAN } +func (m *Dot11MgmtArubaWLAN) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtArubaWLAN } diff --git a/vendor/github.com/google/gopacket/layers/dot11_test.go b/vendor/github.com/google/gopacket/layers/dot11_test.go new file mode 100644 index 0000000..b0299fc --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/dot11_test.go @@ -0,0 +1,495 @@ +// Copyright 2014, Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "bytes" + "net" + "reflect" + "testing" + + "github.com/google/gopacket" +) + +// Generator: python layers/test_creator.py --layerType=LayerTypeRadioTap --linkType=LinkTypeIEEE80211Radio --name=Dot11%s ~/Downloads/mesh.pcap +// http://wiki.wireshark.org/SampleCaptures#Sample_Captures + +// testPacketDot11CtrlCTS is the packet: +// 09:28:41.830560 20604983us tsft short preamble 24.0 Mb/s 5240 MHz 11a -79dB signal -92dB noise antenna 1 Clear-To-Send RA:d8:a2:5e:97:61:c1 +// 0x0000: 0000 1900 6f08 0000 3768 3a01 0000 0000 ....o...7h:..... +// 0x0010: 1230 7814 4001 b1a4 01c4 0094 00d8 a25e .0x.@..........^ +// 0x0020: 9761 c136 5095 8e .a.6P.. + +var testPacketDot11CtrlCTS = []byte{ + 0x00, 0x00, 0x19, 0x00, 0x6f, 0x08, 0x00, 0x00, 0x37, 0x68, 0x3a, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x12, 0x30, 0x78, 0x14, 0x40, 0x01, 0xb1, 0xa4, 0x01, 0xc4, 0x00, 0x94, 0x00, 0xd8, 0xa2, 0x5e, + 0x97, 0x61, 0xc1, 0x36, 0x50, 0x95, 0x8e, +} + +func TestPacketDot11CtrlCTS(t *testing.T) { + p := gopacket.NewPacket(testPacketDot11CtrlCTS, LinkTypeIEEE80211Radio, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeRadioTap, LayerTypeDot11}, t) + + if got, ok := p.Layer(LayerTypeRadioTap).(*RadioTap); ok { + want := &RadioTap{ + BaseLayer: BaseLayer{ + Contents: []uint8{0x0, 0x0, 0x19, 0x0, 0x6f, 0x8, 0x0, 0x0, 0x37, 0x68, 0x3a, 0x1, 0x0, 0x0, 0x0, 0x0, 0x12, 0x30, 0x78, 0x14, 0x40, 0x1, 0xb1, 0xa4, 0x1}, + Payload: []uint8{0xc4, 0x0, 0x94, 0x0, 0xd8, 0xa2, 0x5e, 0x97, 0x61, 0xc1, 0x36, 0x50, 0x95, 0x8e}, + }, + Version: 0x0, + Length: 0x19, + Present: 0x86f, + TSFT: 0x13a6837, + Flags: 0x12, + Rate: 0x30, + ChannelFrequency: 0x1478, + ChannelFlags: 0x140, + FHSS: 0x0, + DBMAntennaSignal: -79, + DBMAntennaNoise: -92, + LockQuality: 0x0, + TxAttenuation: 0x0, + DBTxAttenuation: 0x0, + DBMTxPower: 0, + Antenna: 1, + DBAntennaSignal: 0x0, + DBAntennaNoise: 0x0, + } + + if !reflect.DeepEqual(got, want) { + t.Errorf("RadioTap packet processing failed:\ngot :\n%#v\n\nwant :\n%#v\n\n", got, want) + } + } + + if got, ok := p.Layer(LayerTypeDot11).(*Dot11); ok { + if !got.ChecksumValid() { + t.Errorf("Dot11 packet processing failed:\nchecksum failed. got :\n%#v\n\n", got) + } + + want := &Dot11{ + BaseLayer: BaseLayer{ + Contents: []uint8{0xc4, 0x0, 0x94, 0x0, 0xd8, 0xa2, 0x5e, 0x97, 0x61, 0xc1}, + Payload: []uint8{}, + }, + Type: Dot11TypeCtrlCTS, + Proto: 0x0, + Flags: 0x0, + DurationID: 0x94, + Address1: net.HardwareAddr{0xd8, 0xa2, 0x5e, 0x97, 0x61, 0xc1}, // check + Address2: net.HardwareAddr(nil), + Address3: net.HardwareAddr(nil), + Address4: net.HardwareAddr(nil), + Checksum: 0x8e955036, + } + + if !reflect.DeepEqual(got, want) { + t.Errorf("Dot11 packet processing failed:\ngot :\n%#v\n\nwant :\n%#v\n\n", got, want) + } + } +} + +func BenchmarkDecodePacketDot11CtrlCTS(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketDot11CtrlCTS, LinkTypeIEEE80211Radio, gopacket.NoCopy) + } +} + +// testPacketDot11MgmtBeacon is the packet: +// 15:44:56.531833 6.0 Mb/s 2412 MHz 11g -81dB signal antenna 5 Beacon (Wi2) [6.0* 9.0 12.0* 18.0 24.0* 36.0 48.0 54.0 Mbit] ESS CH: 1 +// 0x0000: 0000 1200 2e48 0000 100c 6c09 c000 af05 .....H....l..... +// 0x0010: 0000 8000 0000 ffff ffff ffff c08a de01 ................ +// 0x0020: 11b8 c08a de01 11b8 f097 80f1 30bc 1300 ............0... +// 0x0030: 0000 6400 2104 0003 5769 3201 088c 1298 ..d.!...Wi2..... +// 0x0040: 24b0 4860 6c03 0101 0504 0001 0000 2a01 $.H`l.........*. +// 0x0050: 00dd 1800 50f2 0201 0181 0007 a400 0023 ....P..........# +// 0x0060: a400 0042 435e 0062 322f 00dd 1e00 904c ...BC^.b2/.....L +// 0x0070: 338c 011b ffff 0000 0000 0000 0000 0000 3............... +// 0x0080: 1000 0000 0000 0000 0000 002d 1a8c 011b ...........-.... +// 0x0090: ffff 0000 0000 0000 0000 0000 1000 0000 ................ +// 0x00a0: 0000 0000 0000 00dd 1a00 904c 3401 0000 ...........L4... +// 0x00b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +// 0x00c0: 0000 003d 1601 0000 0000 0000 0000 0000 ...=............ +// 0x00d0: 0000 0000 0000 0000 0000 007f 0400 0000 ................ +// 0x00e0: 00dd 0800 1392 0100 0185 0094 0b90 15 ............... +var testPacketDot11MgmtBeacon = []byte{ + 0x00, 0x00, 0x12, 0x00, 0x2e, 0x48, 0x00, 0x00, 0x10, 0x0c, 0x6c, 0x09, 0xc0, 0x00, 0xaf, 0x05, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x8a, 0xde, 0x01, + 0x11, 0xb8, 0xc0, 0x8a, 0xde, 0x01, 0x11, 0xb8, 0xf0, 0x97, 0x80, 0xf1, 0x30, 0xbc, 0x13, 0x00, + 0x00, 0x00, 0x64, 0x00, 0x21, 0x04, 0x00, 0x03, 0x57, 0x69, 0x32, 0x01, 0x08, 0x8c, 0x12, 0x98, + 0x24, 0xb0, 0x48, 0x60, 0x6c, 0x03, 0x01, 0x01, 0x05, 0x04, 0x00, 0x01, 0x00, 0x00, 0x2a, 0x01, + 0x00, 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x81, 0x00, 0x07, 0xa4, 0x00, 0x00, 0x23, + 0xa4, 0x00, 0x00, 0x42, 0x43, 0x5e, 0x00, 0x62, 0x32, 0x2f, 0x00, 0xdd, 0x1e, 0x00, 0x90, 0x4c, + 0x33, 0x8c, 0x01, 0x1b, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x1a, 0x8c, 0x01, 0x1b, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdd, 0x1a, 0x00, 0x90, 0x4c, 0x34, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3d, 0x16, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x04, 0x00, 0x00, 0x00, + 0x00, 0xdd, 0x08, 0x00, 0x13, 0x92, 0x01, 0x00, 0x01, 0x85, 0x00, 0x94, 0x0b, 0x90, 0x15, +} + +func TestPacketDot11MgmtBeacon(t *testing.T) { + p := gopacket.NewPacket(testPacketDot11MgmtBeacon, LinkTypeIEEE80211Radio, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + expectedLayers := []gopacket.LayerType{LayerTypeRadioTap, LayerTypeDot11, LayerTypeDot11MgmtBeacon} + for i := 0; i < 12; i++ { + expectedLayers = append(expectedLayers, LayerTypeDot11InformationElement) + } + checkLayers(p, expectedLayers, t) + + if p.Layer(LayerTypeDot11).(*Dot11).SequenceNumber != 2431 { + t.Error("dot11 invalid sequence number") + } + if p.Layer(LayerTypeDot11).(*Dot11).FragmentNumber != 0 { + t.Error("dot11 invalid fragment number") + } + if _, ok := p.Layer(LayerTypeDot11MgmtBeacon).(*Dot11MgmtBeacon); !ok { + t.Errorf("dot11 management beacon frame was expected") + } +} + +func BenchmarkDecodePacketDot11MgmtBeacon(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketDot11MgmtBeacon, LinkTypeIEEE80211Radio, gopacket.NoCopy) + } +} + +// testPacketDot11DataQOSData is the packet: +// 06:14:27.838634 638790765us tsft short preamble 54.0 Mb/s -51dB signal -96dB noise antenna 2 5180 MHz 11a CF +QoS ARP, Request who-has 140.180.51.68 tell 169.254.247.0, length 28 +// 0x0000: 0000 2000 6708 0400 6d2c 1326 0000 0000 ....g...m,.&.... +// 0x0010: 226c cda0 0200 0000 4001 0000 3c14 2411 "l......@...<.$. +// 0x0020: 8801 2c00 0603 7f07 a016 0019 e3d3 5352 ..,...........SR +// 0x0030: ffff ffff ffff 5064 0000 50aa aaaa 0300 ......Pd..P..... +// 0x0040: 0000 0806 0001 0800 0604 0001 0019 e3d3 ................ +// 0x0050: 5352 a9fe f700 0000 0000 0000 8cb4 3344 SR............3D +var testPacketDot11DataQOSData = []byte{ + 0x00, 0x00, 0x20, 0x00, 0x67, 0x08, 0x04, 0x00, 0x6d, 0x2c, 0x13, 0x26, 0x00, 0x00, 0x00, 0x00, + 0x22, 0x6c, 0xcd, 0xa0, 0x02, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x3c, 0x14, 0x24, 0x11, + 0x88, 0x01, 0x2c, 0x00, 0x06, 0x03, 0x7f, 0x07, 0xa0, 0x16, 0x00, 0x19, 0xe3, 0xd3, 0x53, 0x52, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x50, 0x64, 0x00, 0x00, 0x50, 0xaa, 0xaa, 0xaa, 0x03, 0x00, + 0x00, 0x00, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x00, 0x19, 0xe3, 0xd3, + 0x53, 0x52, 0xa9, 0xfe, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0xb4, 0x33, 0x44, +} + +func TestPacketDot11DataQOSData(t *testing.T) { + p := gopacket.NewPacket(testPacketDot11DataQOSData, LinkTypeIEEE80211Radio, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeRadioTap, LayerTypeDot11, LayerTypeDot11DataQOSData, LayerTypeDot11Data, LayerTypeLLC, LayerTypeSNAP, LayerTypeARP}, t) + + if got, ok := p.Layer(LayerTypeARP).(*ARP); ok { + want := &ARP{BaseLayer: BaseLayer{ + Contents: []uint8{0x0, 0x1, 0x8, 0x0, 0x6, 0x4, 0x0, 0x1, 0x0, 0x19, 0xe3, 0xd3, 0x53, 0x52, 0xa9, 0xfe, 0xf7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8c, 0xb4, 0x33, 0x44}, + Payload: []uint8{}, + }, + AddrType: 0x1, + Protocol: 0x800, + HwAddressSize: 0x6, + ProtAddressSize: 0x4, + Operation: 0x1, + SourceHwAddress: []uint8{0x0, 0x19, 0xe3, 0xd3, 0x53, 0x52}, + SourceProtAddress: []uint8{0xa9, 0xfe, 0xf7, 0x0}, + DstHwAddress: []uint8{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, + DstProtAddress: []uint8{0x8c, 0xb4, 0x33, 0x44}, + } + + if !reflect.DeepEqual(got, want) { + t.Errorf("ARP packet processing failed:\ngot :\n%#v\n\nwant :\n%#v\n\n", got, want) + } + } +} +func BenchmarkDecodePacketDot11DataQOSData(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketDot11DataQOSData, LinkTypeIEEE80211Radio, gopacket.NoCopy) + } +} + +// testPacketDot11MgmtAction is the packet: +// 15:54:43.236460 1.0 Mb/s 2412 MHz 11b -67dB signal antenna 5 Action (8e:3a:e3:44:ac:c6): Spectrum Management Act#4 +// 0x0000: 0000 1200 2e48 0000 1002 6c09 a000 bd05 .....H....l..... +// 0x0010: 0000 d000 0000 ffff ffff ffff 8e3a e344 .............:.D +// 0x0020: acc6 8e3a e344 acc6 001b 0004 2503 0001 ...:.D......%... +// 0x0030: 0055 39f0 33 .U9.3 +var testPacketDot11MgmtAction = []byte{ + 0x00, 0x00, 0x12, 0x00, 0x2e, 0x48, 0x00, 0x00, 0x10, 0x02, 0x6c, 0x09, 0xa0, 0x00, 0xbd, 0x05, + 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8e, 0x3a, 0xe3, 0x44, + 0xac, 0xc6, 0x8e, 0x3a, 0xe3, 0x44, 0xac, 0xc6, 0x00, 0x1b, 0x00, 0x04, 0x25, 0x03, 0x00, 0x01, + 0x00, 0x55, 0x39, 0xf0, 0x33, +} + +func TestPacketDot11MgmtAction(t *testing.T) { + p := gopacket.NewPacket(testPacketDot11MgmtAction, LinkTypeIEEE80211Radio, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeRadioTap, LayerTypeDot11, LayerTypeDot11MgmtAction}, t) + if got, ok := p.Layer(LayerTypeDot11).(*Dot11); !ok { + t.Errorf("dot11 frame was not parsed") + } else if !got.ChecksumValid() { + t.Errorf("Dot11 packet processing failed: checksum failed") + } + if got, ok := p.Layer(LayerTypeDot11MgmtAction).(*Dot11MgmtAction); !ok { + t.Errorf("management action frame was not parsed") + } else if got.Contents[0] != 0 { + t.Errorf("action category was not spectrum management") + } +} + +func BenchmarkDecodePacketDot11MgmtAction(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketDot11MgmtAction, LinkTypeIEEE80211Radio, gopacket.NoCopy) + } +} + +// testPacketDot11CtrlAck is the packet: +// 06:14:27.838669 638758038us tsft short preamble 24.0 Mb/s -39dB signal -96dB noise antenna 2 5180 MHz 11a Acknowledgment RA:00:19:e3:d3:53:52 +// 0x0000: 0000 2000 6708 0400 96ac 1226 0000 0000 ....g......&.... +// 0x0010: 2230 d9a0 0200 0000 4001 0000 3c14 2411 "0......@...<.$. +// 0x0020: d400 0000 0019 e3d3 5352 46e9 7687 ........SRF.v. +var testPacketDot11CtrlAck = []byte{ + 0x00, 0x00, 0x20, 0x00, 0x67, 0x08, 0x04, 0x00, 0x96, 0xac, 0x12, 0x26, 0x00, 0x00, 0x00, 0x00, + 0x32, 0x30, 0xd9, 0xa0, 0x02, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x3c, 0x14, 0x24, 0x11, + 0xd4, 0x00, 0x00, 0x00, 0x00, 0x19, 0xe3, 0xd3, 0x53, 0x52, 0x46, 0xe9, 0x76, 0x87, +} + +func TestPacketDot11CtrlAck(t *testing.T) { + p := gopacket.NewPacket(testPacketDot11CtrlAck, LinkTypeIEEE80211Radio, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeRadioTap, LayerTypeDot11}, t) + + if got, ok := p.Layer(LayerTypeDot11).(*Dot11); ok { + if !got.ChecksumValid() { + t.Errorf("Dot11 packet processing failed:\nchecksum failed. got :\n%#v\n\n", got) + } + } + + if got, ok := p.Layer(LayerTypeDot11).(*Dot11); ok { + if !got.ChecksumValid() { + t.Errorf("Dot11 packet processing failed:\nchecksum failed. got :\n%#v\n\n", got) + } + want := &Dot11{ + BaseLayer: BaseLayer{ + Contents: []uint8{0xd4, 0x0, 0x0, 0x0, 0x0, 0x19, 0xe3, 0xd3, 0x53, 0x52}, + Payload: []uint8{}, + }, + Type: Dot11TypeCtrlAck, + Proto: 0x0, + Flags: 0x0, + DurationID: 0x0, + Address1: net.HardwareAddr{0x0, 0x19, 0xe3, 0xd3, 0x53, 0x52}, + Address2: net.HardwareAddr(nil), + Address3: net.HardwareAddr(nil), + Address4: net.HardwareAddr(nil), + Checksum: 0x8776e946, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("Dot11 packet processing failed:\ngot :\n%#v\n\nwant :\n%#v\n\n", got, want) + } + } +} +func BenchmarkDecodePacketDot11CtrlAck(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketDot11CtrlAck, LinkTypeIEEE80211Radio, gopacket.NoCopy) + } +} + +// testPacketDot11DataARP is the packet: +// 06:14:11.512316 622463798us tsft short preamble 6.0 Mb/s -39dB signal -96dB noise antenna 2 5180 MHz 11a ARP, Request who-has 67.8.14.54 tell 169.254.247.0, length 28 +// 0x0000: 0000 2000 6708 0400 360b 1a25 0000 0000 ....g...6..%.... +// 0x0010: 220c d9a0 0200 0000 4001 0000 3c14 2411 ".......@...<.$. +// 0x0020: 0802 0000 ffff ffff ffff 0603 7f07 a016 ................ +// 0x0030: 0019 e3d3 5352 e07f aaaa 0300 0000 0806 ....SR.......... +// 0x0040: 0001 0800 0604 0001 0019 e3d3 5352 a9fe ............SR.. +// 0x0050: f700 0000 0000 0000 4308 0e36 ........C..6 +var testPacketDot11DataARP = []byte{ + 0x00, 0x00, 0x20, 0x00, 0x67, 0x08, 0x04, 0x00, 0x36, 0x0b, 0x1a, 0x25, 0x00, 0x00, 0x00, 0x00, + 0x22, 0x0c, 0xd9, 0xa0, 0x02, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x3c, 0x14, 0x24, 0x11, + 0x08, 0x02, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x06, 0x03, 0x7f, 0x07, 0xa0, 0x16, + 0x00, 0x19, 0xe3, 0xd3, 0x53, 0x52, 0xe0, 0x7f, 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06, + 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x00, 0x19, 0xe3, 0xd3, 0x53, 0x52, 0xa9, 0xfe, + 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x08, 0x0e, 0x36, +} + +func TestPacketDot11DataARP(t *testing.T) { + p := gopacket.NewPacket(testPacketDot11DataARP, LinkTypeIEEE80211Radio, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeRadioTap, LayerTypeDot11, LayerTypeDot11Data, LayerTypeLLC, LayerTypeSNAP, LayerTypeARP}, t) + + if got, ok := p.Layer(LayerTypeARP).(*ARP); ok { + want := &ARP{ + BaseLayer: BaseLayer{ + Contents: []uint8{0x0, 0x1, 0x8, 0x0, 0x6, 0x4, 0x0, 0x1, 0x0, 0x19, 0xe3, 0xd3, 0x53, 0x52, 0xa9, 0xfe, 0xf7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x43, 0x8, 0xe, 0x36}, + Payload: []uint8{}, + }, + AddrType: 0x1, + Protocol: 0x800, + HwAddressSize: 0x6, + ProtAddressSize: 0x4, + Operation: 0x1, + SourceHwAddress: []uint8{0x0, 0x19, 0xe3, 0xd3, 0x53, 0x52}, + SourceProtAddress: []uint8{0xa9, 0xfe, 0xf7, 0x0}, + DstHwAddress: []uint8{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, + DstProtAddress: []uint8{0x43, 0x8, 0xe, 0x36}, + } + + if !reflect.DeepEqual(got, want) { + t.Errorf("ARP packet processing failed:\ngot :\n%#v\n\nwant :\n%#v\n\n", got, want) + } + } +} + +func BenchmarkDecodePacketDot11DataARP(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketDot11DataARP, LinkTypeIEEE80211Radio, gopacket.NoCopy) + } +} + +// testPacketDot11DataIP is the packet: +// 06:14:21.388622 632340487us tsft short preamble 6.0 Mb/s -40dB signal -96dB noise antenna 1 5180 MHz 11a IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from 00:19:e3:d3:53:52, length 300 +// 0x0000: 0000 2000 6708 0400 07c0 b025 0000 0000 ....g......%.... +// 0x0010: 220c d8a0 0100 0000 4001 0000 3c14 2411 ".......@...<.$. +// 0x0020: 0802 0000 ffff ffff ffff 0603 7f07 a016 ................ +// 0x0030: 0019 e3d3 5352 4095 aaaa 0300 0000 0800 ....SR@......... +// 0x0040: 4500 0148 c514 0000 ff11 f590 0000 0000 E..H............ +// 0x0050: ffff ffff 0044 0043 0134 2b39 0101 0600 .....D.C.4+9.... +// 0x0060: 131f 8c43 003c 0000 0000 0000 0000 0000 ...C.<.......... +// 0x0070: 0000 0000 0000 0000 0019 e3d3 5352 0000 ............SR.. +// 0x0080: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +// 0x0090: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +// 0x00a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +// 0x00b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +// 0x00c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +// 0x00d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +// 0x00e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +// 0x00f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +// 0x0100: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +// 0x0110: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +// 0x0120: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +// 0x0130: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +// 0x0140: 0000 0000 0000 0000 6382 5363 3501 0137 ........c.Sc5..7 +// 0x0150: 0a01 0306 0f77 5ffc 2c2e 2f39 0205 dc3d .....w_.,./9...= +// 0x0160: 0701 0019 e3d3 5352 3304 0076 a700 0c0b ......SR3..v.... +// 0x0170: 4d61 6369 6e74 6f73 682d 34ff 0000 0000 Macintosh-4..... +// 0x0180: 0000 0000 0000 0000 ........ +var testPacketDot11DataIP = []byte{ + 0x00, 0x00, 0x20, 0x00, 0x67, 0x08, 0x04, 0x00, 0x07, 0xc0, 0xb0, 0x25, 0x00, 0x00, 0x00, 0x00, + 0x22, 0x0c, 0xd8, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x3c, 0x14, 0x24, 0x11, + 0x08, 0x02, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x06, 0x03, 0x7f, 0x07, 0xa0, 0x16, + 0x00, 0x19, 0xe3, 0xd3, 0x53, 0x52, 0x40, 0x95, 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x45, 0x00, 0x01, 0x48, 0xc5, 0x14, 0x00, 0x00, 0xff, 0x11, 0xf5, 0x90, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x44, 0x00, 0x43, 0x01, 0x34, 0x2b, 0x39, 0x01, 0x01, 0x06, 0x00, + 0x13, 0x1f, 0x8c, 0x43, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xe3, 0xd3, 0x53, 0x52, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x01, 0x37, + 0x0a, 0x01, 0x03, 0x06, 0x0f, 0x77, 0x5f, 0xfc, 0x2c, 0x2e, 0x2f, 0x39, 0x02, 0x05, 0xdc, 0x3d, + 0x07, 0x01, 0x00, 0x19, 0xe3, 0xd3, 0x53, 0x52, 0x33, 0x04, 0x00, 0x76, 0xa7, 0x00, 0x0c, 0x0b, + 0x4d, 0x61, 0x63, 0x69, 0x6e, 0x74, 0x6f, 0x73, 0x68, 0x2d, 0x34, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +} + +func TestPacketDot11DataIP(t *testing.T) { + p := gopacket.NewPacket(testPacketDot11DataIP, LinkTypeIEEE80211Radio, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeRadioTap, LayerTypeDot11, LayerTypeDot11Data, LayerTypeLLC, LayerTypeSNAP, LayerTypeIPv4, LayerTypeUDP, LayerTypeDHCPv4}, t) +} +func BenchmarkDecodePacketDot11DataIP(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketDot11DataIP, LinkTypeIEEE80211Radio, gopacket.NoCopy) + } +} + +// Encrypted + +/// testPacketP6196 is the packet: +// 09:28:41.830631 20605036us tsft wep -69dB signal -92dB noise antenna 1 5240 MHz 11a ht/40- 162.0 Mb/s MCS 12 40 MHz lon GI mixed BCC FEC [bit 20] CF +QoS Data IV:50a9 Pad 20 KeyID 0 +// 0x0000: 0000 3000 6b08 1c00 6c68 3a01 0000 0000 ..0.k...lh:..... +// 0x0010: 1400 7814 4001 bba4 0160 0e1a 4001 0400 ..x.@....`..@... +// 0x0020: 7814 3022 1f01 0cff b10d 0000 0400 0000 x.0"............ +// 0x0030: 8841 2c00 0025 9c42 c262 d8a2 5e97 61c1 .A,..%.B.b..^.a. +// 0x0040: 0025 9c42 c25f 10db 0000 a950 0020 0000 .%.B._.....P.... +// 0x0050: 0000 f8ab a97e 3fbd d6e1 785b 0040 5f15 .....~?...x[.@_. +// 0x0060: 7123 8711 bd1f ffb9 e5b3 84bb ec2a 0a90 q#...........*.. +// 0x0070: d0a0 1a6f 9033 1083 5179 a0da f833 3a00 ...o.3..Qy...3:. +// 0x0080: 5471 f596 539b 1823 a33c 4908 545c 266a Tq..S..#.<I.T\&j +// 0x0090: 8540 515a 1da9 c49e a85a fbf7 de09 7f9c .@QZ.....Z...... +// 0x00a0: 6f35 0b8b 6831 2c10 43dc 8983 b1d9 dd29 o5..h1,.C......) +// 0x00b0: 7395 65b9 4b43 b391 16ec 4201 86c9 ca s.e.KC....B.... +var testPacketP6196 = []byte{ + 0x00, 0x00, 0x30, 0x00, 0x6b, 0x08, 0x1c, 0x00, 0x6c, 0x68, 0x3a, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x78, 0x14, 0x40, 0x01, 0xbb, 0xa4, 0x01, 0x60, 0x0e, 0x1a, 0x40, 0x01, 0x04, 0x00, + 0x78, 0x14, 0x30, 0x22, 0x1f, 0x01, 0x0c, 0xff, 0xb1, 0x0d, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x88, 0x41, 0x2c, 0x00, 0x00, 0x25, 0x9c, 0x42, 0xc2, 0x62, 0xd8, 0xa2, 0x5e, 0x97, 0x61, 0xc1, + 0x00, 0x25, 0x9c, 0x42, 0xc2, 0x5f, 0x10, 0xdb, 0x00, 0x00, 0xa9, 0x50, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0xab, 0xa9, 0x7e, 0x3f, 0xbd, 0xd6, 0xe1, 0x78, 0x5b, 0x00, 0x40, 0x5f, 0x15, + 0x71, 0x23, 0x87, 0x11, 0xbd, 0x1f, 0xff, 0xb9, 0xe5, 0xb3, 0x84, 0xbb, 0xec, 0x2a, 0x0a, 0x90, + 0xd0, 0xa0, 0x1a, 0x6f, 0x90, 0x33, 0x10, 0x83, 0x51, 0x79, 0xa0, 0xda, 0xf8, 0x33, 0x3a, 0x00, + 0x54, 0x71, 0xf5, 0x96, 0x53, 0x9b, 0x18, 0x23, 0xa3, 0x3c, 0x49, 0x08, 0x54, 0x5c, 0x26, 0x6a, + 0x85, 0x40, 0x51, 0x5a, 0x1d, 0xa9, 0xc4, 0x9e, 0xa8, 0x5a, 0xfb, 0xf7, 0xde, 0x09, 0x7f, 0x9c, + 0x6f, 0x35, 0x0b, 0x8b, 0x68, 0x31, 0x2c, 0x10, 0x43, 0xdc, 0x89, 0x83, 0xb1, 0xd9, 0xdd, 0x29, + 0x73, 0x95, 0x65, 0xb9, 0x4b, 0x43, 0xb3, 0x91, 0x16, 0xec, 0x42, 0x01, 0x86, 0xc9, 0xca, +} + +func TestPacketP6196(t *testing.T) { + p := gopacket.NewPacket(testPacketP6196, LinkTypeIEEE80211Radio, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + + checkLayers(p, []gopacket.LayerType{LayerTypeRadioTap, LayerTypeDot11, LayerTypeDot11WEP}, t) +} + +func BenchmarkDecodePacketP6196(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketP6196, LinkTypeIEEE80211Radio, gopacket.NoCopy) + } +} + +func TestInformationElement(t *testing.T) { + bin := []byte{ + 0, 0, + 0, 2, 1, 3, + 221, 5, 1, 2, 3, 4, 5, + } + pkt := gopacket.NewPacket(bin, LayerTypeDot11InformationElement, gopacket.NoCopy) + + buf := gopacket.NewSerializeBuffer() + var sLayers []gopacket.SerializableLayer + for _, l := range pkt.Layers() { + sLayers = append(sLayers, l.(*Dot11InformationElement)) + } + if err := gopacket.SerializeLayers(buf, gopacket.SerializeOptions{}, sLayers...); err != nil { + t.Error(err.Error()) + } + if !bytes.Equal(bin, buf.Bytes()) { + t.Error("build failed") + } +} diff --git a/vendor/github.com/google/gopacket/layers/dot1q.go b/vendor/github.com/google/gopacket/layers/dot1q.go new file mode 100644 index 0000000..47f93d7 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/dot1q.go @@ -0,0 +1,71 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// Copyright 2009-2011 Andreas Krennmair. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "fmt" + "github.com/google/gopacket" +) + +// Dot1Q is the packet layer for 802.1Q VLAN headers. +type Dot1Q struct { + BaseLayer + Priority uint8 + DropEligible bool + VLANIdentifier uint16 + Type EthernetType +} + +// LayerType returns gopacket.LayerTypeDot1Q +func (d *Dot1Q) LayerType() gopacket.LayerType { return LayerTypeDot1Q } + +// DecodeFromBytes decodes the given bytes into this layer. +func (d *Dot1Q) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + d.Priority = (data[0] & 0xE0) >> 5 + d.DropEligible = data[0]&0x10 != 0 + d.VLANIdentifier = binary.BigEndian.Uint16(data[:2]) & 0x0FFF + d.Type = EthernetType(binary.BigEndian.Uint16(data[2:4])) + d.BaseLayer = BaseLayer{Contents: data[:4], Payload: data[4:]} + return nil +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (d *Dot1Q) CanDecode() gopacket.LayerClass { + return LayerTypeDot1Q +} + +// NextLayerType returns the layer type contained by this DecodingLayer. +func (d *Dot1Q) NextLayerType() gopacket.LayerType { + return d.Type.LayerType() +} + +func decodeDot1Q(data []byte, p gopacket.PacketBuilder) error { + d := &Dot1Q{} + return decodingLayerDecoder(d, data, p) +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (d *Dot1Q) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + bytes, err := b.PrependBytes(4) + if err != nil { + return err + } + if d.VLANIdentifier > 0xFFF { + return fmt.Errorf("vlan identifier %v is too high", d.VLANIdentifier) + } + firstBytes := uint16(d.Priority)<<13 | d.VLANIdentifier + if d.DropEligible { + firstBytes |= 0x1000 + } + binary.BigEndian.PutUint16(bytes, firstBytes) + binary.BigEndian.PutUint16(bytes[2:], uint16(d.Type)) + return nil +} diff --git a/vendor/github.com/google/gopacket/layers/dot1q_test.go b/vendor/github.com/google/gopacket/layers/dot1q_test.go new file mode 100644 index 0000000..4a409c7 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/dot1q_test.go @@ -0,0 +1,62 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. +package layers + +import ( + "fmt" + "reflect" + "testing" + + "github.com/google/gopacket" +) + +// test harness to ensure the dot1q layer can be encoded/decoded properly +// return error if decoded data not match. +func testEncodeDecodeDot1Q(dot1Q *Dot1Q) error { + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{} + expectedDot1Q := dot1Q + + err := dot1Q.SerializeTo(buf, opts) + if err != nil { + return err + } + + newDot1q := &Dot1Q{} + err = newDot1q.DecodeFromBytes(buf.Bytes(), gopacket.NilDecodeFeedback) + if err != nil { + return err + } + newDot1q.BaseLayer = BaseLayer{} + + if !reflect.DeepEqual(expectedDot1Q, newDot1q) { + return fmt.Errorf("Expect %v actual %v", expectedDot1Q, newDot1q) + } + return nil + +} + +// Test to ensure what has been encode can be decoded +func TestEncodeDecodeDot1Q(t *testing.T) { + dot1Qs := []*Dot1Q{ + &Dot1Q{ + Priority: uint8(3), + VLANIdentifier: uint16(30), + }, + &Dot1Q{ + Priority: uint8(0x07), + DropEligible: true, + VLANIdentifier: uint16(0xFFF), + }, + } + + for i, curTest := range dot1Qs { + err := testEncodeDecodeDot1Q(curTest) + if err != nil { + t.Error("Error with item ", i, " with error message :", err) + } + } +} diff --git a/vendor/github.com/google/gopacket/layers/eap.go b/vendor/github.com/google/gopacket/layers/eap.go new file mode 100644 index 0000000..250f857 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/eap.go @@ -0,0 +1,106 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "fmt" + "github.com/google/gopacket" +) + +type EAPCode uint8 +type EAPType uint8 + +const ( + EAPCodeRequest EAPCode = 1 + EAPCodeResponse EAPCode = 2 + EAPCodeSuccess EAPCode = 3 + EAPCodeFailure EAPCode = 4 + + // EAPTypeNone means that this EAP layer has no Type or TypeData. + // Success and Failure EAPs will have this set. + EAPTypeNone EAPType = 0 + + EAPTypeIdentity EAPType = 1 + EAPTypeNotification EAPType = 2 + EAPTypeNACK EAPType = 3 + EAPTypeOTP EAPType = 4 + EAPTypeTokenCard EAPType = 5 +) + +// EAP defines an Extensible Authentication Protocol (rfc 3748) layer. +type EAP struct { + BaseLayer + Code EAPCode + Id uint8 + Length uint16 + Type EAPType + TypeData []byte +} + +// LayerType returns LayerTypeEAP. +func (e *EAP) LayerType() gopacket.LayerType { return LayerTypeEAP } + +// DecodeFromBytes decodes the given bytes into this layer. +func (e *EAP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + e.Code = EAPCode(data[0]) + e.Id = data[1] + e.Length = binary.BigEndian.Uint16(data[2:4]) + switch { + case e.Length > 4: + e.Type = EAPType(data[4]) + e.TypeData = data[5:] + case e.Length == 4: + e.Type = 0 + e.TypeData = nil + default: + return fmt.Errorf("invalid EAP length %d", e.Length) + } + e.BaseLayer.Contents = data[:e.Length] + e.BaseLayer.Payload = data[e.Length:] // Should be 0 bytes + return nil +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (e *EAP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + if opts.FixLengths { + e.Length = uint16(len(e.TypeData) + 1) + } + size := len(e.TypeData) + 4 + if size > 4 { + size++ + } + bytes, err := b.PrependBytes(size) + if err != nil { + return err + } + bytes[0] = byte(e.Code) + bytes[1] = e.Id + binary.BigEndian.PutUint16(bytes[2:], e.Length) + if size > 4 { + bytes[4] = byte(e.Type) + copy(bytes[5:], e.TypeData) + } + return nil +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (e *EAP) CanDecode() gopacket.LayerClass { + return LayerTypeEAP +} + +// NextLayerType returns the layer type contained by this DecodingLayer. +func (e *EAP) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypeZero +} + +func decodeEAP(data []byte, p gopacket.PacketBuilder) error { + e := &EAP{} + return decodingLayerDecoder(e, data, p) +} diff --git a/vendor/github.com/google/gopacket/layers/eapol.go b/vendor/github.com/google/gopacket/layers/eapol.go new file mode 100644 index 0000000..041cd59 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/eapol.go @@ -0,0 +1,57 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "github.com/google/gopacket" +) + +// EAPOL defines an EAP over LAN (802.1x) layer. +type EAPOL struct { + BaseLayer + Version uint8 + Type EAPOLType + Length uint16 +} + +// LayerType returns LayerTypeEAPOL. +func (e *EAPOL) LayerType() gopacket.LayerType { return LayerTypeEAPOL } + +// DecodeFromBytes decodes the given bytes into this layer. +func (e *EAPOL) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + e.Version = data[0] + e.Type = EAPOLType(data[1]) + e.Length = binary.BigEndian.Uint16(data[2:4]) + e.BaseLayer = BaseLayer{data[:4], data[4:]} + return nil +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer +func (e *EAPOL) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + bytes, _ := b.PrependBytes(4) + bytes[0] = e.Version + bytes[1] = byte(e.Type) + binary.BigEndian.PutUint16(bytes[2:], e.Length) + return nil +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (e *EAPOL) CanDecode() gopacket.LayerClass { + return LayerTypeEAPOL +} + +// NextLayerType returns the layer type contained by this DecodingLayer. +func (e *EAPOL) NextLayerType() gopacket.LayerType { + return e.Type.LayerType() +} + +func decodeEAPOL(data []byte, p gopacket.PacketBuilder) error { + e := &EAPOL{} + return decodingLayerDecoder(e, data, p) +} diff --git a/vendor/github.com/google/gopacket/layers/endpoints.go b/vendor/github.com/google/gopacket/layers/endpoints.go new file mode 100644 index 0000000..4c91cc3 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/endpoints.go @@ -0,0 +1,97 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "github.com/google/gopacket" + "net" + "strconv" +) + +var ( + // We use two different endpoint types for IPv4 vs IPv6 addresses, so that + // ordering with endpointA.LessThan(endpointB) sanely groups all IPv4 + // addresses and all IPv6 addresses, such that IPv6 > IPv4 for all addresses. + EndpointIPv4 = gopacket.RegisterEndpointType(1, gopacket.EndpointTypeMetadata{Name: "IPv4", Formatter: func(b []byte) string { + return net.IP(b).String() + }}) + EndpointIPv6 = gopacket.RegisterEndpointType(2, gopacket.EndpointTypeMetadata{Name: "IPv6", Formatter: func(b []byte) string { + return net.IP(b).String() + }}) + + EndpointMAC = gopacket.RegisterEndpointType(3, gopacket.EndpointTypeMetadata{Name: "MAC", Formatter: func(b []byte) string { + return net.HardwareAddr(b).String() + }}) + EndpointTCPPort = gopacket.RegisterEndpointType(4, gopacket.EndpointTypeMetadata{Name: "TCP", Formatter: func(b []byte) string { + return strconv.Itoa(int(binary.BigEndian.Uint16(b))) + }}) + EndpointUDPPort = gopacket.RegisterEndpointType(5, gopacket.EndpointTypeMetadata{Name: "UDP", Formatter: func(b []byte) string { + return strconv.Itoa(int(binary.BigEndian.Uint16(b))) + }}) + EndpointSCTPPort = gopacket.RegisterEndpointType(6, gopacket.EndpointTypeMetadata{Name: "SCTP", Formatter: func(b []byte) string { + return strconv.Itoa(int(binary.BigEndian.Uint16(b))) + }}) + EndpointRUDPPort = gopacket.RegisterEndpointType(7, gopacket.EndpointTypeMetadata{Name: "RUDP", Formatter: func(b []byte) string { + return strconv.Itoa(int(b[0])) + }}) + EndpointUDPLitePort = gopacket.RegisterEndpointType(8, gopacket.EndpointTypeMetadata{Name: "UDPLite", Formatter: func(b []byte) string { + return strconv.Itoa(int(binary.BigEndian.Uint16(b))) + }}) + EndpointPPP = gopacket.RegisterEndpointType(9, gopacket.EndpointTypeMetadata{Name: "PPP", Formatter: func([]byte) string { + return "point" + }}) +) + +// NewIPEndpoint creates a new IP (v4 or v6) endpoint from a net.IP address. +// It returns gopacket.InvalidEndpoint if the IP address is invalid. +func NewIPEndpoint(a net.IP) gopacket.Endpoint { + ipv4 := a.To4() + if ipv4 != nil { + return gopacket.NewEndpoint(EndpointIPv4, []byte(ipv4)) + } + + ipv6 := a.To16() + if ipv6 != nil { + return gopacket.NewEndpoint(EndpointIPv6, []byte(ipv6)) + } + + return gopacket.InvalidEndpoint +} + +// NewMACEndpoint returns a new MAC address endpoint. +func NewMACEndpoint(a net.HardwareAddr) gopacket.Endpoint { + return gopacket.NewEndpoint(EndpointMAC, []byte(a)) +} +func newPortEndpoint(t gopacket.EndpointType, p uint16) gopacket.Endpoint { + return gopacket.NewEndpoint(t, []byte{byte(p >> 8), byte(p)}) +} + +// NewTCPPortEndpoint returns an endpoint based on a TCP port. +func NewTCPPortEndpoint(p TCPPort) gopacket.Endpoint { + return newPortEndpoint(EndpointTCPPort, uint16(p)) +} + +// NewUDPPortEndpoint returns an endpoint based on a UDP port. +func NewUDPPortEndpoint(p UDPPort) gopacket.Endpoint { + return newPortEndpoint(EndpointUDPPort, uint16(p)) +} + +// NewSCTPPortEndpoint returns an endpoint based on a SCTP port. +func NewSCTPPortEndpoint(p SCTPPort) gopacket.Endpoint { + return newPortEndpoint(EndpointSCTPPort, uint16(p)) +} + +// NewRUDPPortEndpoint returns an endpoint based on a RUDP port. +func NewRUDPPortEndpoint(p RUDPPort) gopacket.Endpoint { + return gopacket.NewEndpoint(EndpointRUDPPort, []byte{byte(p)}) +} + +// NewUDPLitePortEndpoint returns an endpoint based on a UDPLite port. +func NewUDPLitePortEndpoint(p UDPLitePort) gopacket.Endpoint { + return newPortEndpoint(EndpointUDPLitePort, uint16(p)) +} diff --git a/vendor/github.com/google/gopacket/layers/endpoints_test.go b/vendor/github.com/google/gopacket/layers/endpoints_test.go new file mode 100644 index 0000000..906762a --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/endpoints_test.go @@ -0,0 +1,37 @@ +// Copyright 2017, Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "net" + "testing" + + "github.com/google/gopacket" +) + +func TestNewIPEndpoint(t *testing.T) { + cases := []struct { + ip net.IP + endpointType gopacket.EndpointType + }{ + {net.ParseIP("192.168.0.1").To4(), EndpointIPv4}, + {net.ParseIP("192.168.0.1").To16(), EndpointIPv4}, + {net.ParseIP("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), EndpointIPv6}, + } + + for _, c := range cases { + endpoint := NewIPEndpoint(c.ip) + if endpoint == gopacket.InvalidEndpoint { + t.Errorf("Failed to create an IP endpoint for %s (%d-bytes)", + c.ip, len(c.ip)) + } + if endpoint.EndpointType() != c.endpointType { + t.Errorf("Wrong endpoint type created for %s (%d-bytes): expected %s, got %s", + c.ip, len(c.ip), c.endpointType, endpoint.EndpointType()) + } + } +} diff --git a/vendor/github.com/google/gopacket/layers/enums.go b/vendor/github.com/google/gopacket/layers/enums.go new file mode 100644 index 0000000..0ea2058 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/enums.go @@ -0,0 +1,564 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// Copyright 2009-2011 Andreas Krennmair. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "errors" + "fmt" + + "github.com/google/gopacket" +) + +// EnumMetadata keeps track of a set of metadata for each enumeration value +// for protocol enumerations. +type EnumMetadata struct { + // DecodeWith is the decoder to use to decode this protocol's data. + DecodeWith gopacket.Decoder + // Name is the name of the enumeration value. + Name string + // LayerType is the layer type implied by the given enum. + LayerType gopacket.LayerType +} + +// errorFunc returns a decoder that spits out a specific error message. +func errorFunc(msg string) gopacket.Decoder { + var e = errors.New(msg) + return gopacket.DecodeFunc(func([]byte, gopacket.PacketBuilder) error { + return e + }) +} + +// EthernetType is an enumeration of ethernet type values, and acts as a decoder +// for any type it supports. +type EthernetType uint16 + +const ( + // EthernetTypeLLC is not an actual ethernet type. It is instead a + // placeholder we use in Ethernet frames that use the 802.3 standard of + // srcmac|dstmac|length|LLC instead of srcmac|dstmac|ethertype. + EthernetTypeLLC EthernetType = 0 + EthernetTypeIPv4 EthernetType = 0x0800 + EthernetTypeARP EthernetType = 0x0806 + EthernetTypeIPv6 EthernetType = 0x86DD + EthernetTypeCiscoDiscovery EthernetType = 0x2000 + EthernetTypeNortelDiscovery EthernetType = 0x01a2 + EthernetTypeTransparentEthernetBridging EthernetType = 0x6558 + EthernetTypeDot1Q EthernetType = 0x8100 + EthernetTypePPPoEDiscovery EthernetType = 0x8863 + EthernetTypePPPoESession EthernetType = 0x8864 + EthernetTypeMPLSUnicast EthernetType = 0x8847 + EthernetTypeMPLSMulticast EthernetType = 0x8848 + EthernetTypeEAPOL EthernetType = 0x888e + EthernetTypeQinQ EthernetType = 0x88a8 + EthernetTypeLinkLayerDiscovery EthernetType = 0x88cc + EthernetTypeEthernetCTP EthernetType = 0x9000 +) + +// IPProtocol is an enumeration of IP protocol values, and acts as a decoder +// for any type it supports. +type IPProtocol uint8 + +const ( + IPProtocolIPv6HopByHop IPProtocol = 0 + IPProtocolICMPv4 IPProtocol = 1 + IPProtocolIGMP IPProtocol = 2 + IPProtocolIPv4 IPProtocol = 4 + IPProtocolTCP IPProtocol = 6 + IPProtocolUDP IPProtocol = 17 + IPProtocolRUDP IPProtocol = 27 + IPProtocolIPv6 IPProtocol = 41 + IPProtocolIPv6Routing IPProtocol = 43 + IPProtocolIPv6Fragment IPProtocol = 44 + IPProtocolGRE IPProtocol = 47 + IPProtocolESP IPProtocol = 50 + IPProtocolAH IPProtocol = 51 + IPProtocolICMPv6 IPProtocol = 58 + IPProtocolNoNextHeader IPProtocol = 59 + IPProtocolIPv6Destination IPProtocol = 60 + IPProtocolOSPF IPProtocol = 89 + IPProtocolIPIP IPProtocol = 94 + IPProtocolEtherIP IPProtocol = 97 + IPProtocolVRRP IPProtocol = 112 + IPProtocolSCTP IPProtocol = 132 + IPProtocolUDPLite IPProtocol = 136 + IPProtocolMPLSInIP IPProtocol = 137 +) + +// LinkType is an enumeration of link types, and acts as a decoder for any +// link type it supports. +type LinkType uint8 + +const ( + // According to pcap-linktype(7) and http://www.tcpdump.org/linktypes.html + LinkTypeNull LinkType = 0 + LinkTypeEthernet LinkType = 1 + LinkTypeAX25 LinkType = 3 + LinkTypeTokenRing LinkType = 6 + LinkTypeArcNet LinkType = 7 + LinkTypeSLIP LinkType = 8 + LinkTypePPP LinkType = 9 + LinkTypeFDDI LinkType = 10 + LinkTypePPP_HDLC LinkType = 50 + LinkTypePPPEthernet LinkType = 51 + LinkTypeATM_RFC1483 LinkType = 100 + LinkTypeRaw LinkType = 101 + LinkTypeC_HDLC LinkType = 104 + LinkTypeIEEE802_11 LinkType = 105 + LinkTypeFRelay LinkType = 107 + LinkTypeLoop LinkType = 108 + LinkTypeLinuxSLL LinkType = 113 + LinkTypeLTalk LinkType = 114 + LinkTypePFLog LinkType = 117 + LinkTypePrismHeader LinkType = 119 + LinkTypeIPOverFC LinkType = 122 + LinkTypeSunATM LinkType = 123 + LinkTypeIEEE80211Radio LinkType = 127 + LinkTypeARCNetLinux LinkType = 129 + LinkTypeIPOver1394 LinkType = 138 + LinkTypeMTP2Phdr LinkType = 139 + LinkTypeMTP2 LinkType = 140 + LinkTypeMTP3 LinkType = 141 + LinkTypeSCCP LinkType = 142 + LinkTypeDOCSIS LinkType = 143 + LinkTypeLinuxIRDA LinkType = 144 + LinkTypeLinuxLAPD LinkType = 177 + LinkTypeLinuxUSB LinkType = 220 + LinkTypeIPv4 LinkType = 228 + LinkTypeIPv6 LinkType = 229 +) + +// PPPoECode is the PPPoE code enum, taken from http://tools.ietf.org/html/rfc2516 +type PPPoECode uint8 + +const ( + PPPoECodePADI PPPoECode = 0x09 + PPPoECodePADO PPPoECode = 0x07 + PPPoECodePADR PPPoECode = 0x19 + PPPoECodePADS PPPoECode = 0x65 + PPPoECodePADT PPPoECode = 0xA7 + PPPoECodeSession PPPoECode = 0x00 +) + +// PPPType is an enumeration of PPP type values, and acts as a decoder for any +// type it supports. +type PPPType uint16 + +const ( + PPPTypeIPv4 PPPType = 0x0021 + PPPTypeIPv6 PPPType = 0x0057 + PPPTypeMPLSUnicast PPPType = 0x0281 + PPPTypeMPLSMulticast PPPType = 0x0283 +) + +// SCTPChunkType is an enumeration of chunk types inside SCTP packets. +type SCTPChunkType uint8 + +const ( + SCTPChunkTypeData SCTPChunkType = 0 + SCTPChunkTypeInit SCTPChunkType = 1 + SCTPChunkTypeInitAck SCTPChunkType = 2 + SCTPChunkTypeSack SCTPChunkType = 3 + SCTPChunkTypeHeartbeat SCTPChunkType = 4 + SCTPChunkTypeHeartbeatAck SCTPChunkType = 5 + SCTPChunkTypeAbort SCTPChunkType = 6 + SCTPChunkTypeShutdown SCTPChunkType = 7 + SCTPChunkTypeShutdownAck SCTPChunkType = 8 + SCTPChunkTypeError SCTPChunkType = 9 + SCTPChunkTypeCookieEcho SCTPChunkType = 10 + SCTPChunkTypeCookieAck SCTPChunkType = 11 + SCTPChunkTypeShutdownComplete SCTPChunkType = 14 +) + +// FDDIFrameControl is an enumeration of FDDI frame control bytes. +type FDDIFrameControl uint8 + +const ( + FDDIFrameControlLLC FDDIFrameControl = 0x50 +) + +// EAPOLType is an enumeration of EAPOL packet types. +type EAPOLType uint8 + +const ( + EAPOLTypeEAP EAPOLType = 0 + EAPOLTypeStart EAPOLType = 1 + EAPOLTypeLogOff EAPOLType = 2 + EAPOLTypeKey EAPOLType = 3 + EAPOLTypeASFAlert EAPOLType = 4 +) + +// ProtocolFamily is the set of values defined as PF_* in sys/socket.h +type ProtocolFamily uint8 + +const ( + ProtocolFamilyIPv4 ProtocolFamily = 2 + // BSDs use different values for INET6... glory be. These values taken from + // tcpdump 4.3.0. + ProtocolFamilyIPv6BSD ProtocolFamily = 24 + ProtocolFamilyIPv6FreeBSD ProtocolFamily = 28 + ProtocolFamilyIPv6Darwin ProtocolFamily = 30 + ProtocolFamilyIPv6Linux ProtocolFamily = 10 +) + +// Dot11Type is a combination of IEEE 802.11 frame's Type and Subtype fields. +// By combining these two fields together into a single type, we're able to +// provide a String function that correctly displays the subtype given the +// top-level type. +// +// If you just care about the top-level type, use the MainType function. +type Dot11Type uint8 + +// MainType strips the subtype information from the given type, +// returning just the overarching type (Mgmt, Ctrl, Data, Reserved). +func (d Dot11Type) MainType() Dot11Type { + return d & dot11TypeMask +} + +const ( + Dot11TypeMgmt Dot11Type = 0x00 + Dot11TypeCtrl Dot11Type = 0x01 + Dot11TypeData Dot11Type = 0x02 + Dot11TypeReserved Dot11Type = 0x03 + dot11TypeMask = 0x03 + + // The following are type/subtype conglomerations. + + // Management + Dot11TypeMgmtAssociationReq Dot11Type = 0x00 + Dot11TypeMgmtAssociationResp Dot11Type = 0x04 + Dot11TypeMgmtReassociationReq Dot11Type = 0x08 + Dot11TypeMgmtReassociationResp Dot11Type = 0x0c + Dot11TypeMgmtProbeReq Dot11Type = 0x10 + Dot11TypeMgmtProbeResp Dot11Type = 0x14 + Dot11TypeMgmtMeasurementPilot Dot11Type = 0x18 + Dot11TypeMgmtBeacon Dot11Type = 0x20 + Dot11TypeMgmtATIM Dot11Type = 0x24 + Dot11TypeMgmtDisassociation Dot11Type = 0x28 + Dot11TypeMgmtAuthentication Dot11Type = 0x2c + Dot11TypeMgmtDeauthentication Dot11Type = 0x30 + Dot11TypeMgmtAction Dot11Type = 0x34 + Dot11TypeMgmtActionNoAck Dot11Type = 0x38 + + // Control + Dot11TypeCtrlWrapper Dot11Type = 0x1d + Dot11TypeCtrlBlockAckReq Dot11Type = 0x21 + Dot11TypeCtrlBlockAck Dot11Type = 0x25 + Dot11TypeCtrlPowersavePoll Dot11Type = 0x29 + Dot11TypeCtrlRTS Dot11Type = 0x2d + Dot11TypeCtrlCTS Dot11Type = 0x31 + Dot11TypeCtrlAck Dot11Type = 0x35 + Dot11TypeCtrlCFEnd Dot11Type = 0x39 + Dot11TypeCtrlCFEndAck Dot11Type = 0x3d + + // Data + Dot11TypeDataCFAck Dot11Type = 0x06 + Dot11TypeDataCFPoll Dot11Type = 0x0a + Dot11TypeDataCFAckPoll Dot11Type = 0x0e + Dot11TypeDataNull Dot11Type = 0x12 + Dot11TypeDataCFAckNoData Dot11Type = 0x16 + Dot11TypeDataCFPollNoData Dot11Type = 0x1a + Dot11TypeDataCFAckPollNoData Dot11Type = 0x1e + Dot11TypeDataQOSData Dot11Type = 0x22 + Dot11TypeDataQOSDataCFAck Dot11Type = 0x26 + Dot11TypeDataQOSDataCFPoll Dot11Type = 0x2a + Dot11TypeDataQOSDataCFAckPoll Dot11Type = 0x2e + Dot11TypeDataQOSNull Dot11Type = 0x32 + Dot11TypeDataQOSCFPollNoData Dot11Type = 0x3a + Dot11TypeDataQOSCFAckPollNoData Dot11Type = 0x3e +) + +var ( + // Each of the following arrays contains mappings of how to handle enum + // values for various enum types in gopacket/layers. + // + // So, EthernetTypeMetadata[2] contains information on how to handle EthernetType + // 2, including which name to give it and which decoder to use to decode + // packet data of that type. These arrays are filled by default with all of the + // protocols gopacket/layers knows how to handle, but users of the library can + // add new decoders or override existing ones. For example, if you write a better + // TCP decoder, you can override IPProtocolMetadata[IPProtocolTCP].DecodeWith + // with your new decoder, and all gopacket/layers decoding will use your new + // decoder whenever they encounter that IPProtocol. + EthernetTypeMetadata [65536]EnumMetadata + IPProtocolMetadata [256]EnumMetadata + SCTPChunkTypeMetadata [256]EnumMetadata + PPPTypeMetadata [65536]EnumMetadata + PPPoECodeMetadata [256]EnumMetadata + LinkTypeMetadata [256]EnumMetadata + FDDIFrameControlMetadata [256]EnumMetadata + EAPOLTypeMetadata [256]EnumMetadata + ProtocolFamilyMetadata [256]EnumMetadata + Dot11TypeMetadata [256]EnumMetadata + USBTypeMetadata [256]EnumMetadata +) + +func (a EthernetType) Decode(data []byte, p gopacket.PacketBuilder) error { + return EthernetTypeMetadata[a].DecodeWith.Decode(data, p) +} +func (a EthernetType) String() string { + return EthernetTypeMetadata[a].Name +} +func (a EthernetType) LayerType() gopacket.LayerType { + return EthernetTypeMetadata[a].LayerType +} +func (a IPProtocol) Decode(data []byte, p gopacket.PacketBuilder) error { + return IPProtocolMetadata[a].DecodeWith.Decode(data, p) +} +func (a IPProtocol) String() string { + return IPProtocolMetadata[a].Name +} +func (a IPProtocol) LayerType() gopacket.LayerType { + return IPProtocolMetadata[a].LayerType +} +func (a SCTPChunkType) Decode(data []byte, p gopacket.PacketBuilder) error { + return SCTPChunkTypeMetadata[a].DecodeWith.Decode(data, p) +} +func (a SCTPChunkType) String() string { + return SCTPChunkTypeMetadata[a].Name +} +func (a PPPType) Decode(data []byte, p gopacket.PacketBuilder) error { + return PPPTypeMetadata[a].DecodeWith.Decode(data, p) +} +func (a PPPType) String() string { + return PPPTypeMetadata[a].Name +} +func (a LinkType) Decode(data []byte, p gopacket.PacketBuilder) error { + return LinkTypeMetadata[a].DecodeWith.Decode(data, p) +} +func (a LinkType) String() string { + return LinkTypeMetadata[a].Name +} +func (a PPPoECode) Decode(data []byte, p gopacket.PacketBuilder) error { + return PPPoECodeMetadata[a].DecodeWith.Decode(data, p) +} +func (a PPPoECode) String() string { + return PPPoECodeMetadata[a].Name +} +func (a FDDIFrameControl) Decode(data []byte, p gopacket.PacketBuilder) error { + return FDDIFrameControlMetadata[a].DecodeWith.Decode(data, p) +} +func (a FDDIFrameControl) String() string { + return FDDIFrameControlMetadata[a].Name +} +func (a EAPOLType) Decode(data []byte, p gopacket.PacketBuilder) error { + return EAPOLTypeMetadata[a].DecodeWith.Decode(data, p) +} +func (a EAPOLType) String() string { + return EAPOLTypeMetadata[a].Name +} +func (a EAPOLType) LayerType() gopacket.LayerType { + return EAPOLTypeMetadata[a].LayerType +} +func (a ProtocolFamily) Decode(data []byte, p gopacket.PacketBuilder) error { + return ProtocolFamilyMetadata[a].DecodeWith.Decode(data, p) +} +func (a ProtocolFamily) String() string { + return ProtocolFamilyMetadata[a].Name +} +func (a ProtocolFamily) LayerType() gopacket.LayerType { + return ProtocolFamilyMetadata[a].LayerType +} +func (a Dot11Type) Decode(data []byte, p gopacket.PacketBuilder) error { + return Dot11TypeMetadata[a].DecodeWith.Decode(data, p) +} +func (a Dot11Type) String() string { + return Dot11TypeMetadata[a].Name +} +func (a Dot11Type) LayerType() gopacket.LayerType { + return Dot11TypeMetadata[a].LayerType +} + +// Decode a raw v4 or v6 IP packet. +func decodeIPv4or6(data []byte, p gopacket.PacketBuilder) error { + version := data[0] >> 4 + switch version { + case 4: + return decodeIPv4(data, p) + case 6: + return decodeIPv6(data, p) + } + return fmt.Errorf("Invalid IP packet version %v", version) +} + +func init() { + // Here we link up all enumerations with their respective names and decoders. + for i := 0; i < 65536; i++ { + EthernetTypeMetadata[i] = EnumMetadata{ + DecodeWith: errorFunc(fmt.Sprintf("Unable to decode ethernet type %d", i)), + Name: fmt.Sprintf("UnknownEthernetType(%d)", i), + } + PPPTypeMetadata[i] = EnumMetadata{ + DecodeWith: errorFunc(fmt.Sprintf("Unable to decode PPP type %d", i)), + Name: fmt.Sprintf("UnknownPPPType(%d)", i), + } + } + for i := 0; i < 256; i++ { + IPProtocolMetadata[i] = EnumMetadata{ + DecodeWith: errorFunc(fmt.Sprintf("Unable to decode IP protocol %d", i)), + Name: fmt.Sprintf("UnknownIPProtocol(%d)", i), + } + SCTPChunkTypeMetadata[i] = EnumMetadata{ + DecodeWith: errorFunc(fmt.Sprintf("Unable to decode SCTP chunk type %d", i)), + Name: fmt.Sprintf("UnknownSCTPChunkType(%d)", i), + } + PPPoECodeMetadata[i] = EnumMetadata{ + DecodeWith: errorFunc(fmt.Sprintf("Unable to decode PPPoE code %d", i)), + Name: fmt.Sprintf("UnknownPPPoECode(%d)", i), + } + LinkTypeMetadata[i] = EnumMetadata{ + DecodeWith: errorFunc(fmt.Sprintf("Unable to decode link type %d", i)), + Name: fmt.Sprintf("UnknownLinkType(%d)", i), + } + FDDIFrameControlMetadata[i] = EnumMetadata{ + DecodeWith: errorFunc(fmt.Sprintf("Unable to decode FDDI frame control %d", i)), + Name: fmt.Sprintf("UnknownFDDIFrameControl(%d)", i), + } + EAPOLTypeMetadata[i] = EnumMetadata{ + DecodeWith: errorFunc(fmt.Sprintf("Unable to decode EAPOL type %d", i)), + Name: fmt.Sprintf("UnknownEAPOLType(%d)", i), + } + ProtocolFamilyMetadata[i] = EnumMetadata{ + DecodeWith: errorFunc(fmt.Sprintf("Unable to decode protocol family %d", i)), + Name: fmt.Sprintf("UnknownProtocolFamily(%d)", i), + } + Dot11TypeMetadata[i] = EnumMetadata{ + DecodeWith: errorFunc(fmt.Sprintf("Unable to decode Dot11 type %d", i)), + Name: fmt.Sprintf("UnknownDot11Type(%d)", i), + } + } + + EthernetTypeMetadata[EthernetTypeLLC] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeLLC), Name: "LLC", LayerType: LayerTypeLLC} + EthernetTypeMetadata[EthernetTypeIPv4] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4), Name: "IPv4", LayerType: LayerTypeIPv4} + EthernetTypeMetadata[EthernetTypeIPv6] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6), Name: "IPv6", LayerType: LayerTypeIPv6} + EthernetTypeMetadata[EthernetTypeARP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeARP), Name: "ARP", LayerType: LayerTypeARP} + EthernetTypeMetadata[EthernetTypeDot1Q] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot1Q), Name: "Dot1Q", LayerType: LayerTypeDot1Q} + EthernetTypeMetadata[EthernetTypePPPoEDiscovery] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePPPoE), Name: "PPPoEDiscovery", LayerType: LayerTypePPPoE} + EthernetTypeMetadata[EthernetTypePPPoESession] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePPPoE), Name: "PPPoESession", LayerType: LayerTypePPPoE} + EthernetTypeMetadata[EthernetTypeEthernetCTP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEthernetCTP), Name: "EthernetCTP", LayerType: LayerTypeEthernetCTP} + EthernetTypeMetadata[EthernetTypeCiscoDiscovery] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeCiscoDiscovery), Name: "CiscoDiscovery", LayerType: LayerTypeCiscoDiscovery} + EthernetTypeMetadata[EthernetTypeNortelDiscovery] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeNortelDiscovery), Name: "NortelDiscovery", LayerType: LayerTypeNortelDiscovery} + EthernetTypeMetadata[EthernetTypeLinkLayerDiscovery] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeLinkLayerDiscovery), Name: "LinkLayerDiscovery", LayerType: LayerTypeLinkLayerDiscovery} + EthernetTypeMetadata[EthernetTypeMPLSUnicast] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeMPLS), Name: "MPLSUnicast", LayerType: LayerTypeMPLS} + EthernetTypeMetadata[EthernetTypeMPLSMulticast] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeMPLS), Name: "MPLSMulticast", LayerType: LayerTypeMPLS} + EthernetTypeMetadata[EthernetTypeEAPOL] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEAPOL), Name: "EAPOL", LayerType: LayerTypeEAPOL} + EthernetTypeMetadata[EthernetTypeQinQ] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot1Q), Name: "Dot1Q", LayerType: LayerTypeDot1Q} + EthernetTypeMetadata[EthernetTypeTransparentEthernetBridging] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEthernet), Name: "TransparentEthernetBridging", LayerType: LayerTypeEthernet} + + IPProtocolMetadata[IPProtocolIPv4] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4), Name: "IPv4", LayerType: LayerTypeIPv4} + IPProtocolMetadata[IPProtocolTCP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeTCP), Name: "TCP", LayerType: LayerTypeTCP} + IPProtocolMetadata[IPProtocolUDP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeUDP), Name: "UDP", LayerType: LayerTypeUDP} + IPProtocolMetadata[IPProtocolICMPv4] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeICMPv4), Name: "ICMPv4", LayerType: LayerTypeICMPv4} + IPProtocolMetadata[IPProtocolICMPv6] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeICMPv6), Name: "ICMPv6", LayerType: LayerTypeICMPv6} + IPProtocolMetadata[IPProtocolSCTP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTP), Name: "SCTP", LayerType: LayerTypeSCTP} + IPProtocolMetadata[IPProtocolIPv6] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6), Name: "IPv6", LayerType: LayerTypeIPv6} + IPProtocolMetadata[IPProtocolIPIP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4), Name: "IPv4", LayerType: LayerTypeIPv4} + IPProtocolMetadata[IPProtocolEtherIP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEtherIP), Name: "EtherIP", LayerType: LayerTypeEtherIP} + IPProtocolMetadata[IPProtocolRUDP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeRUDP), Name: "RUDP", LayerType: LayerTypeRUDP} + IPProtocolMetadata[IPProtocolGRE] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeGRE), Name: "GRE", LayerType: LayerTypeGRE} + IPProtocolMetadata[IPProtocolIPv6HopByHop] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6HopByHop), Name: "IPv6HopByHop", LayerType: LayerTypeIPv6HopByHop} + IPProtocolMetadata[IPProtocolIPv6Routing] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6Routing), Name: "IPv6Routing", LayerType: LayerTypeIPv6Routing} + IPProtocolMetadata[IPProtocolIPv6Fragment] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6Fragment), Name: "IPv6Fragment", LayerType: LayerTypeIPv6Fragment} + IPProtocolMetadata[IPProtocolIPv6Destination] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6Destination), Name: "IPv6Destination", LayerType: LayerTypeIPv6Destination} + IPProtocolMetadata[IPProtocolOSPF] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeOSPF), Name: "OSPF", LayerType: LayerTypeOSPF} + IPProtocolMetadata[IPProtocolAH] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPSecAH), Name: "IPSecAH", LayerType: LayerTypeIPSecAH} + IPProtocolMetadata[IPProtocolESP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPSecESP), Name: "IPSecESP", LayerType: LayerTypeIPSecESP} + IPProtocolMetadata[IPProtocolUDPLite] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeUDPLite), Name: "UDPLite", LayerType: LayerTypeUDPLite} + IPProtocolMetadata[IPProtocolMPLSInIP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeMPLS), Name: "MPLS", LayerType: LayerTypeMPLS} + IPProtocolMetadata[IPProtocolNoNextHeader] = EnumMetadata{DecodeWith: gopacket.DecodePayload, Name: "NoNextHeader", LayerType: gopacket.LayerTypePayload} + IPProtocolMetadata[IPProtocolIGMP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIGMP), Name: "IGMP", LayerType: LayerTypeIGMP} + IPProtocolMetadata[IPProtocolVRRP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeVRRP), Name: "VRRP", LayerType: LayerTypeVRRP} + + SCTPChunkTypeMetadata[SCTPChunkTypeData] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPData), Name: "Data"} + SCTPChunkTypeMetadata[SCTPChunkTypeInit] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPInit), Name: "Init"} + SCTPChunkTypeMetadata[SCTPChunkTypeInitAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPInit), Name: "InitAck"} + SCTPChunkTypeMetadata[SCTPChunkTypeSack] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPSack), Name: "Sack"} + SCTPChunkTypeMetadata[SCTPChunkTypeHeartbeat] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPHeartbeat), Name: "Heartbeat"} + SCTPChunkTypeMetadata[SCTPChunkTypeHeartbeatAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPHeartbeat), Name: "HeartbeatAck"} + SCTPChunkTypeMetadata[SCTPChunkTypeAbort] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPError), Name: "Abort"} + SCTPChunkTypeMetadata[SCTPChunkTypeError] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPError), Name: "Error"} + SCTPChunkTypeMetadata[SCTPChunkTypeShutdown] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPShutdown), Name: "Shutdown"} + SCTPChunkTypeMetadata[SCTPChunkTypeShutdownAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPShutdownAck), Name: "ShutdownAck"} + SCTPChunkTypeMetadata[SCTPChunkTypeCookieEcho] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPCookieEcho), Name: "CookieEcho"} + SCTPChunkTypeMetadata[SCTPChunkTypeCookieAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPEmptyLayer), Name: "CookieAck"} + SCTPChunkTypeMetadata[SCTPChunkTypeShutdownComplete] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPEmptyLayer), Name: "ShutdownComplete"} + + PPPTypeMetadata[PPPTypeIPv4] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4), Name: "IPv4"} + PPPTypeMetadata[PPPTypeIPv6] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6), Name: "IPv6"} + PPPTypeMetadata[PPPTypeMPLSUnicast] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeMPLS), Name: "MPLSUnicast"} + PPPTypeMetadata[PPPTypeMPLSMulticast] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeMPLS), Name: "MPLSMulticast"} + + PPPoECodeMetadata[PPPoECodeSession] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePPP), Name: "PPP"} + + LinkTypeMetadata[LinkTypeEthernet] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEthernet), Name: "Ethernet"} + LinkTypeMetadata[LinkTypePPP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePPP), Name: "PPP"} + LinkTypeMetadata[LinkTypeFDDI] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeFDDI), Name: "FDDI"} + LinkTypeMetadata[LinkTypeNull] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeLoopback), Name: "Null"} + LinkTypeMetadata[LinkTypeIEEE802_11] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11), Name: "Dot11"} + LinkTypeMetadata[LinkTypeLoop] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeLoopback), Name: "Loop"} + LinkTypeMetadata[LinkTypeIEEE802_11] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11), Name: "802.11"} + LinkTypeMetadata[LinkTypeRaw] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4or6), Name: "Raw"} + LinkTypeMetadata[LinkTypePFLog] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePFLog), Name: "PFLog"} + LinkTypeMetadata[LinkTypeIEEE80211Radio] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeRadioTap), Name: "RadioTap"} + LinkTypeMetadata[LinkTypeLinuxUSB] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeUSB), Name: "USB"} + LinkTypeMetadata[LinkTypeLinuxSLL] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeLinuxSLL), Name: "Linux SLL"} + LinkTypeMetadata[LinkTypePrismHeader] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePrismHeader), Name: "Prism"} + + FDDIFrameControlMetadata[FDDIFrameControlLLC] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeLLC), Name: "LLC"} + + EAPOLTypeMetadata[EAPOLTypeEAP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEAP), Name: "EAP", LayerType: LayerTypeEAP} + + ProtocolFamilyMetadata[ProtocolFamilyIPv4] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4), Name: "IPv4", LayerType: LayerTypeIPv4} + ProtocolFamilyMetadata[ProtocolFamilyIPv6BSD] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6), Name: "IPv6", LayerType: LayerTypeIPv6} + ProtocolFamilyMetadata[ProtocolFamilyIPv6FreeBSD] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6), Name: "IPv6", LayerType: LayerTypeIPv6} + ProtocolFamilyMetadata[ProtocolFamilyIPv6Darwin] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6), Name: "IPv6", LayerType: LayerTypeIPv6} + ProtocolFamilyMetadata[ProtocolFamilyIPv6Linux] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6), Name: "IPv6", LayerType: LayerTypeIPv6} + + Dot11TypeMetadata[Dot11TypeMgmtAssociationReq] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtAssociationReq), Name: "MgmtAssociationReq", LayerType: LayerTypeDot11MgmtAssociationReq} + Dot11TypeMetadata[Dot11TypeMgmtAssociationResp] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtAssociationResp), Name: "MgmtAssociationResp", LayerType: LayerTypeDot11MgmtAssociationResp} + Dot11TypeMetadata[Dot11TypeMgmtReassociationReq] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtReassociationReq), Name: "MgmtReassociationReq", LayerType: LayerTypeDot11MgmtReassociationReq} + Dot11TypeMetadata[Dot11TypeMgmtReassociationResp] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtReassociationResp), Name: "MgmtReassociationResp", LayerType: LayerTypeDot11MgmtReassociationResp} + Dot11TypeMetadata[Dot11TypeMgmtProbeReq] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtProbeReq), Name: "MgmtProbeReq", LayerType: LayerTypeDot11MgmtProbeReq} + Dot11TypeMetadata[Dot11TypeMgmtProbeResp] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtProbeResp), Name: "MgmtProbeResp", LayerType: LayerTypeDot11MgmtProbeResp} + Dot11TypeMetadata[Dot11TypeMgmtMeasurementPilot] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtMeasurementPilot), Name: "MgmtMeasurementPilot", LayerType: LayerTypeDot11MgmtMeasurementPilot} + Dot11TypeMetadata[Dot11TypeMgmtBeacon] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtBeacon), Name: "MgmtBeacon", LayerType: LayerTypeDot11MgmtBeacon} + Dot11TypeMetadata[Dot11TypeMgmtATIM] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtATIM), Name: "MgmtATIM", LayerType: LayerTypeDot11MgmtATIM} + Dot11TypeMetadata[Dot11TypeMgmtDisassociation] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtDisassociation), Name: "MgmtDisassociation", LayerType: LayerTypeDot11MgmtDisassociation} + Dot11TypeMetadata[Dot11TypeMgmtAuthentication] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtAuthentication), Name: "MgmtAuthentication", LayerType: LayerTypeDot11MgmtAuthentication} + Dot11TypeMetadata[Dot11TypeMgmtDeauthentication] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtDeauthentication), Name: "MgmtDeauthentication", LayerType: LayerTypeDot11MgmtDeauthentication} + Dot11TypeMetadata[Dot11TypeMgmtAction] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtAction), Name: "MgmtAction", LayerType: LayerTypeDot11MgmtAction} + Dot11TypeMetadata[Dot11TypeMgmtActionNoAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtActionNoAck), Name: "MgmtActionNoAck", LayerType: LayerTypeDot11MgmtActionNoAck} + Dot11TypeMetadata[Dot11TypeCtrl] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11Ctrl), Name: "Ctrl", LayerType: LayerTypeDot11Ctrl} + Dot11TypeMetadata[Dot11TypeCtrlWrapper] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11Ctrl), Name: "CtrlWrapper", LayerType: LayerTypeDot11Ctrl} + Dot11TypeMetadata[Dot11TypeCtrlBlockAckReq] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11CtrlBlockAckReq), Name: "CtrlBlockAckReq", LayerType: LayerTypeDot11CtrlBlockAckReq} + Dot11TypeMetadata[Dot11TypeCtrlBlockAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11CtrlBlockAck), Name: "CtrlBlockAck", LayerType: LayerTypeDot11CtrlBlockAck} + Dot11TypeMetadata[Dot11TypeCtrlPowersavePoll] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11CtrlPowersavePoll), Name: "CtrlPowersavePoll", LayerType: LayerTypeDot11CtrlPowersavePoll} + Dot11TypeMetadata[Dot11TypeCtrlRTS] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11CtrlRTS), Name: "CtrlRTS", LayerType: LayerTypeDot11CtrlRTS} + Dot11TypeMetadata[Dot11TypeCtrlCTS] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11CtrlCTS), Name: "CtrlCTS", LayerType: LayerTypeDot11CtrlCTS} + Dot11TypeMetadata[Dot11TypeCtrlAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11CtrlAck), Name: "CtrlAck", LayerType: LayerTypeDot11CtrlAck} + Dot11TypeMetadata[Dot11TypeCtrlCFEnd] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11CtrlCFEnd), Name: "CtrlCFEnd", LayerType: LayerTypeDot11CtrlCFEnd} + Dot11TypeMetadata[Dot11TypeCtrlCFEndAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11CtrlCFEndAck), Name: "CtrlCFEndAck", LayerType: LayerTypeDot11CtrlCFEndAck} + Dot11TypeMetadata[Dot11TypeData] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11Data), Name: "Data", LayerType: LayerTypeDot11Data} + Dot11TypeMetadata[Dot11TypeDataCFAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataCFAck), Name: "DataCFAck", LayerType: LayerTypeDot11DataCFAck} + Dot11TypeMetadata[Dot11TypeDataCFPoll] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataCFPoll), Name: "DataCFPoll", LayerType: LayerTypeDot11DataCFPoll} + Dot11TypeMetadata[Dot11TypeDataCFAckPoll] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataCFAckPoll), Name: "DataCFAckPoll", LayerType: LayerTypeDot11DataCFAckPoll} + Dot11TypeMetadata[Dot11TypeDataNull] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataNull), Name: "DataNull", LayerType: LayerTypeDot11DataNull} + Dot11TypeMetadata[Dot11TypeDataCFAckNoData] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataCFAckNoData), Name: "DataCFAckNoData", LayerType: LayerTypeDot11DataCFAckNoData} + Dot11TypeMetadata[Dot11TypeDataCFPollNoData] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataCFPollNoData), Name: "DataCFPollNoData", LayerType: LayerTypeDot11DataCFPollNoData} + Dot11TypeMetadata[Dot11TypeDataCFAckPollNoData] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataCFAckPollNoData), Name: "DataCFAckPollNoData", LayerType: LayerTypeDot11DataCFAckPollNoData} + Dot11TypeMetadata[Dot11TypeDataQOSData] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataQOSData), Name: "DataQOSData", LayerType: LayerTypeDot11DataQOSData} + Dot11TypeMetadata[Dot11TypeDataQOSDataCFAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataQOSDataCFAck), Name: "DataQOSDataCFAck", LayerType: LayerTypeDot11DataQOSDataCFAck} + Dot11TypeMetadata[Dot11TypeDataQOSDataCFPoll] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataQOSDataCFPoll), Name: "DataQOSDataCFPoll", LayerType: LayerTypeDot11DataQOSDataCFPoll} + Dot11TypeMetadata[Dot11TypeDataQOSDataCFAckPoll] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataQOSDataCFAckPoll), Name: "DataQOSDataCFAckPoll", LayerType: LayerTypeDot11DataQOSDataCFAckPoll} + Dot11TypeMetadata[Dot11TypeDataQOSNull] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataQOSNull), Name: "DataQOSNull", LayerType: LayerTypeDot11DataQOSNull} + Dot11TypeMetadata[Dot11TypeDataQOSCFPollNoData] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataQOSCFPollNoData), Name: "DataQOSCFPollNoData", LayerType: LayerTypeDot11DataQOSCFPollNoData} + Dot11TypeMetadata[Dot11TypeDataQOSCFAckPollNoData] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataQOSCFAckPollNoData), Name: "DataQOSCFAckPollNoData", LayerType: LayerTypeDot11DataQOSCFAckPollNoData} + + USBTypeMetadata[USBTransportTypeInterrupt] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeUSBInterrupt), Name: "Interrupt", LayerType: LayerTypeUSBInterrupt} + USBTypeMetadata[USBTransportTypeControl] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeUSBControl), Name: "Control", LayerType: LayerTypeUSBControl} + USBTypeMetadata[USBTransportTypeBulk] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeUSBBulk), Name: "Bulk", LayerType: LayerTypeUSBBulk} +} diff --git a/vendor/github.com/google/gopacket/layers/etherip.go b/vendor/github.com/google/gopacket/layers/etherip.go new file mode 100644 index 0000000..5b7b722 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/etherip.go @@ -0,0 +1,45 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "github.com/google/gopacket" +) + +// EtherIP is the struct for storing RFC 3378 EtherIP packet headers. +type EtherIP struct { + BaseLayer + Version uint8 + Reserved uint16 +} + +// LayerType returns gopacket.LayerTypeEtherIP. +func (e *EtherIP) LayerType() gopacket.LayerType { return LayerTypeEtherIP } + +// DecodeFromBytes decodes the given bytes into this layer. +func (e *EtherIP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + e.Version = data[0] >> 4 + e.Reserved = binary.BigEndian.Uint16(data[:2]) & 0x0fff + e.BaseLayer = BaseLayer{data[:2], data[2:]} + return nil +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (e *EtherIP) CanDecode() gopacket.LayerClass { + return LayerTypeEtherIP +} + +// NextLayerType returns the layer type contained by this DecodingLayer. +func (e *EtherIP) NextLayerType() gopacket.LayerType { + return LayerTypeEthernet +} + +func decodeEtherIP(data []byte, p gopacket.PacketBuilder) error { + e := &EtherIP{} + return decodingLayerDecoder(e, data, p) +} diff --git a/vendor/github.com/google/gopacket/layers/ethernet.go b/vendor/github.com/google/gopacket/layers/ethernet.go new file mode 100644 index 0000000..4eebf8c --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/ethernet.go @@ -0,0 +1,122 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// Copyright 2009-2011 Andreas Krennmair. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "errors" + "fmt" + "github.com/google/gopacket" + "net" +) + +// EthernetBroadcast is the broadcast MAC address used by Ethernet. +var EthernetBroadcast = net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff} + +// Ethernet is the layer for Ethernet frame headers. +type Ethernet struct { + BaseLayer + SrcMAC, DstMAC net.HardwareAddr + EthernetType EthernetType + // Length is only set if a length field exists within this header. Ethernet + // headers follow two different standards, one that uses an EthernetType, the + // other which defines a length the follows with a LLC header (802.3). If the + // former is the case, we set EthernetType and Length stays 0. In the latter + // case, we set Length and EthernetType = EthernetTypeLLC. + Length uint16 +} + +// LayerType returns LayerTypeEthernet +func (e *Ethernet) LayerType() gopacket.LayerType { return LayerTypeEthernet } + +func (e *Ethernet) LinkFlow() gopacket.Flow { + return gopacket.NewFlow(EndpointMAC, e.SrcMAC, e.DstMAC) +} + +func (eth *Ethernet) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 14 { + return errors.New("Ethernet packet too small") + } + eth.DstMAC = net.HardwareAddr(data[0:6]) + eth.SrcMAC = net.HardwareAddr(data[6:12]) + eth.EthernetType = EthernetType(binary.BigEndian.Uint16(data[12:14])) + eth.BaseLayer = BaseLayer{data[:14], data[14:]} + if eth.EthernetType < 0x0600 { + eth.Length = uint16(eth.EthernetType) + eth.EthernetType = EthernetTypeLLC + if cmp := len(eth.Payload) - int(eth.Length); cmp < 0 { + df.SetTruncated() + } else if cmp > 0 { + // Strip off bytes at the end, since we have too many bytes + eth.Payload = eth.Payload[:len(eth.Payload)-cmp] + } + // fmt.Println(eth) + } + return nil +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (eth *Ethernet) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + if len(eth.DstMAC) != 6 { + return fmt.Errorf("invalid dst MAC: %v", eth.DstMAC) + } + if len(eth.SrcMAC) != 6 { + return fmt.Errorf("invalid src MAC: %v", eth.SrcMAC) + } + payload := b.Bytes() + bytes, err := b.PrependBytes(14) + if err != nil { + return err + } + copy(bytes, eth.DstMAC) + copy(bytes[6:], eth.SrcMAC) + if eth.Length != 0 || eth.EthernetType == EthernetTypeLLC { + if opts.FixLengths { + eth.Length = uint16(len(payload)) + } + if eth.EthernetType != EthernetTypeLLC { + return fmt.Errorf("ethernet type %v not compatible with length value %v", eth.EthernetType, eth.Length) + } else if eth.Length > 0x0600 { + return fmt.Errorf("invalid ethernet length %v", eth.Length) + } + binary.BigEndian.PutUint16(bytes[12:], eth.Length) + } else { + binary.BigEndian.PutUint16(bytes[12:], uint16(eth.EthernetType)) + } + length := len(b.Bytes()) + if length < 60 { + // Pad out to 60 bytes. + padding, err := b.AppendBytes(60 - length) + if err != nil { + return err + } + copy(padding, lotsOfZeros[:]) + } + return nil +} + +func (eth *Ethernet) CanDecode() gopacket.LayerClass { + return LayerTypeEthernet +} + +func (eth *Ethernet) NextLayerType() gopacket.LayerType { + return eth.EthernetType.LayerType() +} + +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) +} diff --git a/vendor/github.com/google/gopacket/layers/fddi.go b/vendor/github.com/google/gopacket/layers/fddi.go new file mode 100644 index 0000000..ed9e195 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/fddi.go @@ -0,0 +1,41 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "github.com/google/gopacket" + "net" +) + +// FDDI contains the header for FDDI frames. +type FDDI struct { + BaseLayer + FrameControl FDDIFrameControl + Priority uint8 + SrcMAC, DstMAC net.HardwareAddr +} + +// LayerType returns LayerTypeFDDI. +func (f *FDDI) LayerType() gopacket.LayerType { return LayerTypeFDDI } + +// LinkFlow returns a new flow of type EndpointMAC. +func (f *FDDI) LinkFlow() gopacket.Flow { + return gopacket.NewFlow(EndpointMAC, f.SrcMAC, f.DstMAC) +} + +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) +} diff --git a/vendor/github.com/google/gopacket/layers/gen.go b/vendor/github.com/google/gopacket/layers/gen.go new file mode 100644 index 0000000..ab7a0c0 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/gen.go @@ -0,0 +1,109 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +// +build ignore + +// This binary pulls known ports from IANA, and uses them to populate +// iana_ports.go's TCPPortNames and UDPPortNames maps. +// +// go run gen.go | gofmt > iana_ports.go +package main + +import ( + "bytes" + "encoding/xml" + "flag" + "fmt" + "io/ioutil" + "net/http" + "os" + "strconv" + "time" +) + +const fmtString = `// Copyright 2012 Google, Inc. All rights reserved. + +package layers + +// Created by gen.go, don't edit manually +// Generated at %s +// Fetched from %q + +// TCPPortNames contains the port names for all TCP ports. +var TCPPortNames = tcpPortNames + +// UDPPortNames contains the port names for all UDP ports. +var UDPPortNames = udpPortNames + +// SCTPPortNames contains the port names for all SCTP ports. +var SCTPPortNames = sctpPortNames + +var tcpPortNames = map[TCPPort]string{ +%s} +var udpPortNames = map[UDPPort]string{ +%s} +var sctpPortNames = map[SCTPPort]string{ +%s} +` + +var url = flag.String("url", "http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml", "URL to grab port numbers from") + +func main() { + fmt.Fprintf(os.Stderr, "Fetching ports from %q\n", *url) + resp, err := http.Get(*url) + if err != nil { + panic(err) + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + panic(err) + } + fmt.Fprintln(os.Stderr, "Parsing XML") + var registry struct { + Records []struct { + Protocol string `xml:"protocol"` + Number string `xml:"number"` + Name string `xml:"name"` + } `xml:"record"` + } + xml.Unmarshal(body, ®istry) + var tcpPorts bytes.Buffer + var udpPorts bytes.Buffer + var sctpPorts bytes.Buffer + done := map[string]map[int]bool{ + "tcp": map[int]bool{}, + "udp": map[int]bool{}, + "sctp": map[int]bool{}, + } + for _, r := range registry.Records { + port, err := strconv.Atoi(r.Number) + if err != nil { + continue + } + if r.Name == "" { + continue + } + var b *bytes.Buffer + switch r.Protocol { + case "tcp": + b = &tcpPorts + case "udp": + b = &udpPorts + case "sctp": + b = &sctpPorts + default: + continue + } + if done[r.Protocol][port] { + continue + } + done[r.Protocol][port] = true + fmt.Fprintf(b, "\t%d: %q,\n", port, r.Name) + } + fmt.Fprintln(os.Stderr, "Writing results to stdout") + fmt.Printf(fmtString, time.Now(), *url, tcpPorts.String(), udpPorts.String(), sctpPorts.String()) +} diff --git a/vendor/github.com/google/gopacket/layers/gen_linted.sh b/vendor/github.com/google/gopacket/layers/gen_linted.sh new file mode 100644 index 0000000..75c701f --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/gen_linted.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +for i in *.go; do golint $i | grep -q . || echo $i; done > .linted diff --git a/vendor/github.com/google/gopacket/layers/geneve.go b/vendor/github.com/google/gopacket/layers/geneve.go new file mode 100644 index 0000000..6dc05cf --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/geneve.go @@ -0,0 +1,98 @@ +// Copyright 2016 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + + "github.com/google/gopacket" +) + +// Geneve is specifed here https://tools.ietf.org/html/draft-ietf-nvo3-geneve-03 +// Geneve Header: +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// |Ver| Opt Len |O|C| Rsvd. | Protocol Type | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Virtual Network Identifier (VNI) | Reserved | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Variable Length Options | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +type Geneve struct { + BaseLayer + Version uint8 // 2 bits + OptionsLength uint8 // 6 bits + OAMPacket bool // 1 bits + CriticalOption bool // 1 bits + Protocol EthernetType // 16 bits + VNI uint32 // 24bits + Options []*GeneveOption +} + +// Geneve Tunnel Options +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Option Class | Type |R|R|R| Length | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Variable Option Data | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +type GeneveOption struct { + Class uint16 // 16 bits + Type uint8 // 8 bits + Flags uint8 // 3 bits + Length uint8 // 5 bits + Data []byte +} + +// LayerType returns LayerTypeGeneve +func (gn *Geneve) LayerType() gopacket.LayerType { return LayerTypeGeneve } + +func decodeGeneveOption(data []byte, gn *Geneve) (*GeneveOption, uint8) { + opt := &GeneveOption{} + + opt.Class = binary.BigEndian.Uint16(data[0:1]) + opt.Type = data[2] + opt.Flags = data[3] >> 4 + opt.Length = data[3] & 0xf + + copy(opt.Data, data[4:opt.Length]) + + return opt, 4 + opt.Length +} + +func (gn *Geneve) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + gn.Version = data[0] >> 7 + gn.OptionsLength = data[0] & 0x3f + + gn.OAMPacket = data[1]&0x80 > 0 + gn.CriticalOption = data[1]&0x40 > 0 + gn.Protocol = EthernetType(binary.BigEndian.Uint16(data[2:4])) + + var buf [4]byte + copy(buf[1:], data[4:7]) + gn.VNI = binary.BigEndian.Uint32(buf[:]) + + offset, length := uint8(8), gn.OptionsLength + for length > 0 { + opt, len := decodeGeneveOption(data[offset:], gn) + gn.Options = append(gn.Options, opt) + + length -= len + offset += len + } + + gn.BaseLayer = BaseLayer{data[:offset], data[offset:]} + + return nil +} + +func (gn *Geneve) NextLayerType() gopacket.LayerType { + return gn.Protocol.LayerType() +} + +func decodeGeneve(data []byte, p gopacket.PacketBuilder) error { + gn := &Geneve{} + return decodingLayerDecoder(gn, data, p) +} diff --git a/vendor/github.com/google/gopacket/layers/geneve_test.go b/vendor/github.com/google/gopacket/layers/geneve_test.go new file mode 100644 index 0000000..ee34d52 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/geneve_test.go @@ -0,0 +1,108 @@ +// Copyright 2016 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "reflect" + "testing" + + "github.com/google/gopacket" +) + +var testPacketGeneve1 = []byte{ + 0x00, 0x04, 0x00, 0x01, 0x00, 0x06, 0xfa, 0x16, 0x3e, 0x23, 0xd3, 0x42, + 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 0x00, 0x86, 0x87, 0x39, 0x40, 0x00, + 0x40, 0x11, 0x31, 0x35, 0xc0, 0xa8, 0x00, 0x53, 0xc0, 0xa8, 0x00, 0x55, + 0x31, 0x57, 0x17, 0xc1, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x65, 0x58, + 0x00, 0x00, 0x00, 0x00, 0xba, 0x09, 0x60, 0x5f, 0xa0, 0x91, 0xa2, 0xfe, + 0x54, 0x48, 0x88, 0x51, 0x08, 0x00, 0x45, 0x00, 0x00, 0x54, 0x01, 0xf6, + 0x40, 0x00, 0x40, 0x01, 0xb7, 0x5f, 0xc0, 0xa8, 0x00, 0x01, 0xc0, 0xa8, + 0x00, 0x02, 0x08, 0x00, 0x79, 0xdf, 0x0c, 0xfa, 0x63, 0xc4, 0x03, 0x0b, + 0x50, 0x58, 0x00, 0x00, 0x00, 0x00, 0xee, 0x2b, 0x0d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, + 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, +} + +var testPacketGeneve2 = []byte{ + 0x12, 0xbe, 0x4e, 0xb6, 0xa7, 0xc7, 0x02, 0x88, 0x0a, 0x81, 0xbd, 0x6d, + 0x08, 0x00, 0x45, 0x00, 0x00, 0x86, 0x20, 0xf2, 0x00, 0x00, 0x40, 0x11, + 0x01, 0x52, 0xac, 0x10, 0x00, 0x01, 0xac, 0x10, 0x00, 0x02, 0x40, 0xa6, + 0x17, 0xc1, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x65, 0x58, 0x00, 0x00, + 0x0a, 0x00, 0xd2, 0x8c, 0xdb, 0x12, 0x53, 0xd5, 0x8e, 0xab, 0xa2, 0xa5, + 0x02, 0xf7, 0x08, 0x00, 0x45, 0x00, 0x00, 0x54, 0x38, 0x1a, 0x40, 0x00, + 0x40, 0x01, 0x81, 0x3b, 0xc0, 0xa8, 0x00, 0x01, 0xc0, 0xa8, 0x00, 0x02, + 0x08, 0x00, 0xdd, 0x9d, 0x7e, 0xde, 0x02, 0xc3, 0xcb, 0x07, 0x51, 0x58, + 0x00, 0x00, 0x00, 0x00, 0xba, 0x8d, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, +} + +func TestDecodeGeneve1(t *testing.T) { + p := gopacket.NewPacket(testPacketGeneve1, LinkTypeLinuxSLL, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{ + LayerTypeLinuxSLL, LayerTypeIPv4, LayerTypeUDP, LayerTypeGeneve, + LayerTypeEthernet, LayerTypeIPv4, LayerTypeICMPv4, gopacket.LayerTypePayload, + }, t) + if got, ok := p.Layer(LayerTypeGeneve).(*Geneve); ok { + want := &Geneve{ + BaseLayer: BaseLayer{ + Contents: testPacketGeneve1[44:52], + Payload: testPacketGeneve1[52:150], + }, + Version: 0x0, + OptionsLength: 0x0, + OAMPacket: false, + CriticalOption: false, + Protocol: EthernetTypeTransparentEthernetBridging, + VNI: 0x0, + } + if !reflect.DeepEqual(want, got) { + t.Errorf("Geneve layer mismatch, \nwant %#v\ngot %#v\n", want, got) + } + } +} + +func TestDecodeGeneve2(t *testing.T) { + p := gopacket.NewPacket(testPacketGeneve2, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{ + LayerTypeEthernet, LayerTypeIPv4, LayerTypeUDP, LayerTypeGeneve, + LayerTypeEthernet, LayerTypeIPv4, LayerTypeICMPv4, gopacket.LayerTypePayload, + }, t) + if got, ok := p.Layer(LayerTypeGeneve).(*Geneve); ok { + want := &Geneve{ + BaseLayer: BaseLayer{ + Contents: testPacketGeneve2[42:50], + Payload: testPacketGeneve2[50:148], + }, + Version: 0x0, + OptionsLength: 0x0, + OAMPacket: false, + CriticalOption: false, + Protocol: EthernetTypeTransparentEthernetBridging, + VNI: 0xa, + } + if !reflect.DeepEqual(want, got) { + t.Errorf("Geneve layer mismatch, \nwant %#v\ngot %#v\n", want, got) + } + } +} + +func BenchmarkDecodeGeneve1(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketGeneve1, LinkTypeEthernet, gopacket.NoCopy) + } +} diff --git a/vendor/github.com/google/gopacket/layers/gre.go b/vendor/github.com/google/gopacket/layers/gre.go new file mode 100644 index 0000000..15d5290 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/gre.go @@ -0,0 +1,185 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + + "github.com/google/gopacket" +) + +// GRE is a Generic Routing Encapsulation header. +type GRE struct { + BaseLayer + ChecksumPresent, RoutingPresent, KeyPresent, SeqPresent, StrictSourceRoute bool + RecursionControl, Flags, Version uint8 + Protocol EthernetType + Checksum, Offset uint16 + Key, Seq uint32 + *GRERouting +} + +// GRERouting is GRE routing information, present if the RoutingPresent flag is +// set. +type GRERouting struct { + AddressFamily uint16 + SREOffset, SRELength uint8 + RoutingInformation []byte + Next *GRERouting +} + +// LayerType returns gopacket.LayerTypeGRE. +func (g *GRE) LayerType() gopacket.LayerType { return LayerTypeGRE } + +// DecodeFromBytes decodes the given bytes into this layer. +func (g *GRE) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + g.ChecksumPresent = data[0]&0x80 != 0 + g.RoutingPresent = data[0]&0x40 != 0 + g.KeyPresent = data[0]&0x20 != 0 + g.SeqPresent = data[0]&0x10 != 0 + g.StrictSourceRoute = data[0]&0x08 != 0 + g.RecursionControl = data[0] & 0x7 + g.Flags = data[1] >> 3 + g.Version = data[1] & 0x7 + g.Protocol = EthernetType(binary.BigEndian.Uint16(data[2:4])) + offset := 4 + if g.ChecksumPresent || g.RoutingPresent { + g.Checksum = binary.BigEndian.Uint16(data[offset : offset+2]) + g.Offset = binary.BigEndian.Uint16(data[offset+2 : offset+4]) + offset += 4 + } + if g.KeyPresent { + g.Key = binary.BigEndian.Uint32(data[offset : offset+4]) + offset += 4 + } + if g.SeqPresent { + g.Seq = binary.BigEndian.Uint32(data[offset : offset+4]) + offset += 4 + } + if g.RoutingPresent { + tail := &g.GRERouting + for { + sre := &GRERouting{ + AddressFamily: binary.BigEndian.Uint16(data[offset : offset+2]), + SREOffset: data[offset+2], + SRELength: data[offset+3], + } + sre.RoutingInformation = data[offset+4 : offset+4+int(sre.SRELength)] + offset += 4 + int(sre.SRELength) + if sre.AddressFamily == 0 && sre.SRELength == 0 { + break + } + (*tail) = sre + tail = &sre.Next + } + } + g.BaseLayer = BaseLayer{data[:offset], data[offset:]} + return nil +} + +// SerializeTo writes the serialized form of this layer into the SerializationBuffer, +// implementing gopacket.SerializableLayer. See the docs for gopacket.SerializableLayer for more info. +func (g *GRE) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + size := 4 + if g.ChecksumPresent || g.RoutingPresent { + size += 4 + } + if g.KeyPresent { + size += 4 + } + if g.SeqPresent { + size += 4 + } + if g.RoutingPresent { + r := g.GRERouting + for r != nil { + size += 4 + int(r.SRELength) + r = r.Next + } + size += 4 + } + buf, err := b.PrependBytes(size) + if err != nil { + return err + } + // Reset any potentially dirty memory in the first 2 bytes, as these use OR to set flags. + buf[0] = 0 + buf[1] = 0 + if g.ChecksumPresent { + buf[0] |= 0x80 + } + if g.RoutingPresent { + buf[0] |= 0x40 + } + if g.KeyPresent { + buf[0] |= 0x20 + } + if g.SeqPresent { + buf[0] |= 0x10 + } + if g.StrictSourceRoute { + buf[0] |= 0x08 + } + buf[0] |= g.RecursionControl + buf[1] |= g.Flags << 3 + buf[1] |= g.Version + binary.BigEndian.PutUint16(buf[2:4], uint16(g.Protocol)) + offset := 4 + if g.ChecksumPresent || g.RoutingPresent { + // Don't write the checksum value yet, as we may need to compute it, + // which requires the entire header be complete. + // Instead we zeroize the memory in case it is dirty. + buf[offset] = 0 + buf[offset+1] = 0 + binary.BigEndian.PutUint16(buf[offset+2:offset+4], g.Offset) + offset += 4 + } + if g.KeyPresent { + binary.BigEndian.PutUint32(buf[offset:offset+4], g.Key) + offset += 4 + } + if g.SeqPresent { + binary.BigEndian.PutUint32(buf[offset:offset+4], g.Seq) + offset += 4 + } + if g.RoutingPresent { + sre := g.GRERouting + for sre != nil { + binary.BigEndian.PutUint16(buf[offset:offset+2], sre.AddressFamily) + buf[offset+2] = sre.SREOffset + buf[offset+3] = sre.SRELength + copy(buf[offset+4:offset+4+int(sre.SRELength)], sre.RoutingInformation) + offset += 4 + int(sre.SRELength) + sre = sre.Next + } + // Terminate routing field with a "NULL" SRE. + binary.BigEndian.PutUint32(buf[offset:offset+4], 0) + } + if g.ChecksumPresent { + if opts.ComputeChecksums { + g.Checksum = tcpipChecksum(b.Bytes(), 0) + } + + binary.BigEndian.PutUint16(buf[4:6], g.Checksum) + } + return nil +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (g *GRE) CanDecode() gopacket.LayerClass { + return LayerTypeGRE +} + +// NextLayerType returns the layer type contained by this DecodingLayer. +func (g *GRE) NextLayerType() gopacket.LayerType { + return g.Protocol.LayerType() +} + +func decodeGRE(data []byte, p gopacket.PacketBuilder) error { + g := &GRE{} + return decodingLayerDecoder(g, data, p) +} diff --git a/vendor/github.com/google/gopacket/layers/gre_test.go b/vendor/github.com/google/gopacket/layers/gre_test.go new file mode 100644 index 0000000..af2e38e --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/gre_test.go @@ -0,0 +1,389 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. +package layers + +import ( + "fmt" + "net" + "reflect" + "testing" + + "github.com/google/gopacket" +) + +// testPacketGRE is the packet: +// 15:08:08.003196 IP 192.168.1.1 > 192.168.1.2: GREv0, length 88: IP 172.16.1.1 > 172.16.2.1: ICMP echo request, id 4724, seq 1, length 64 +// 0x0000: 3a56 6b69 595e 8e7a 12c3 a971 0800 4500 :VkiY^.z...q..E. +// 0x0010: 006c 843c 4000 402f 32d3 c0a8 0101 c0a8 .l.<@.@/2....... +// 0x0020: 0102 0000 0800 4500 0054 0488 4000 4001 ......E..T..@.@. +// 0x0030: dafe ac10 0101 ac10 0201 0800 82c4 1274 ...............t +// 0x0040: 0001 c892 a354 0000 0000 380c 0000 0000 .....T....8..... +// 0x0050: 0000 1011 1213 1415 1617 1819 1a1b 1c1d ................ +// 0x0060: 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d ...!"#$%&'()*+,- +// 0x0070: 2e2f 3031 3233 3435 3637 ./01234567 +var testPacketGRE = []byte{ + 0x3a, 0x56, 0x6b, 0x69, 0x59, 0x5e, 0x8e, 0x7a, 0x12, 0xc3, 0xa9, 0x71, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x6c, 0x84, 0x3c, 0x40, 0x00, 0x40, 0x2f, 0x32, 0xd3, 0xc0, 0xa8, 0x01, 0x01, 0xc0, 0xa8, + 0x01, 0x02, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 0x00, 0x54, 0x04, 0x88, 0x40, 0x00, 0x40, 0x01, + 0xda, 0xfe, 0xac, 0x10, 0x01, 0x01, 0xac, 0x10, 0x02, 0x01, 0x08, 0x00, 0x82, 0xc4, 0x12, 0x74, + 0x00, 0x01, 0xc8, 0x92, 0xa3, 0x54, 0x00, 0x00, 0x00, 0x00, 0x38, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, +} + +func TestPacketGRE(t *testing.T) { + p := gopacket.NewPacket(testPacketGRE, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeGRE, LayerTypeIPv4, LayerTypeICMPv4, gopacket.LayerTypePayload}, t) + if got, ok := p.Layer(LayerTypeGRE).(*GRE); ok { + want := &GRE{ + BaseLayer: BaseLayer{testPacketGRE[34:38], testPacketGRE[38:]}, + Protocol: EthernetTypeIPv4, + } + if !reflect.DeepEqual(want, got) { + t.Errorf("GRE layer mismatch, \nwant %#v\ngot %#v\n", want, got) + } + } +} + +func BenchmarkDecodePacketGRE(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketGRE, LinkTypeEthernet, gopacket.NoCopy) + } +} + +var testIPv4OverGRE = []gopacket.SerializableLayer{ + &Ethernet{ + SrcMAC: net.HardwareAddr{142, 122, 18, 195, 169, 113}, + DstMAC: net.HardwareAddr{58, 86, 107, 105, 89, 94}, + EthernetType: EthernetTypeIPv4, + }, + &IPv4{ + Version: 4, + SrcIP: net.IP{192, 168, 1, 1}, + DstIP: net.IP{192, 168, 1, 2}, + Protocol: IPProtocolGRE, + Flags: IPv4DontFragment, + TTL: 64, + Id: 33852, + IHL: 5, + }, + &GRE{ + Protocol: EthernetTypeIPv4, + }, + &IPv4{ + Version: 4, + SrcIP: net.IP{172, 16, 1, 1}, + DstIP: net.IP{172, 16, 2, 1}, + Protocol: IPProtocolICMPv4, + Flags: IPv4DontFragment, + TTL: 64, + IHL: 5, + Id: 1160, + }, + &ICMPv4{ + TypeCode: CreateICMPv4TypeCode(ICMPv4TypeEchoRequest, 0), + Id: 4724, + Seq: 1, + }, + gopacket.Payload{ + 0xc8, 0x92, 0xa3, 0x54, 0x00, 0x00, 0x00, 0x00, 0x38, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + }, +} + +func TestIPv4OverGREEncode(t *testing.T) { + b := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{ + ComputeChecksums: true, + FixLengths: true, + } + if err := gopacket.SerializeLayers(b, opts, testIPv4OverGRE...); err != nil { + t.Errorf("Unable to serialize: %v", err) + } + p := gopacket.NewPacket(b.Bytes(), LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeGRE, LayerTypeIPv4, LayerTypeICMPv4, gopacket.LayerTypePayload}, t) + if got, want := b.Bytes(), testPacketGRE; !reflect.DeepEqual(want, got) { + t.Errorf("Encoding mismatch, \nwant: %v\ngot %v\n", want, got) + } +} + +func BenchmarkEncodePacketGRE(b *testing.B) { + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{ + ComputeChecksums: true, + FixLengths: true, + } + for i := 0; i < b.N; i++ { + gopacket.SerializeLayers(buf, opts, testIPv4OverGRE...) + buf.Clear() + } +} + +// testPacketEthernetOverGRE is the packet: +// 11:01:38.124768 IP 192.168.1.1 > 192.168.1.2: GREv0, length 102: IP 172.16.1.1 > 172.16.1.2: ICMP echo request, id 3842, seq 1, length 64 +// 0x0000: ea6b 4cd3 5513 d6b9 d880 56ef 0800 4500 .kL.U.....V...E. +// 0x0010: 007a 0acd 4000 402f ac34 c0a8 0101 c0a8 .z..@.@/.4...... +// 0x0020: 0102 0000 6558 aa6a 36e6 c630 6e32 3ec7 ....eX.j6..0n2>. +// 0x0030: 9def 0800 4500 0054 d970 4000 4001 0715 ....E..T.p@.@... +// 0x0040: ac10 0101 ac10 0102 0800 3f15 0f02 0001 ..........?..... +// 0x0050: 82d9 b154 0000 0000 b5e6 0100 0000 0000 ...T............ +// 0x0060: 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f ................ +// 0x0070: 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f .!"#$%&'()*+,-./ +// 0x0080: 3031 3233 3435 3637 01234567 +var testPacketEthernetOverGRE = []byte{ + 0xea, 0x6b, 0x4c, 0xd3, 0x55, 0x13, 0xd6, 0xb9, 0xd8, 0x80, 0x56, 0xef, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x7a, 0x0a, 0xcd, 0x40, 0x00, 0x40, 0x2f, 0xac, 0x34, 0xc0, 0xa8, 0x01, 0x01, 0xc0, 0xa8, + 0x01, 0x02, 0x00, 0x00, 0x65, 0x58, 0xaa, 0x6a, 0x36, 0xe6, 0xc6, 0x30, 0x6e, 0x32, 0x3e, 0xc7, + 0x9d, 0xef, 0x08, 0x00, 0x45, 0x00, 0x00, 0x54, 0xd9, 0x70, 0x40, 0x00, 0x40, 0x01, 0x07, 0x15, + 0xac, 0x10, 0x01, 0x01, 0xac, 0x10, 0x01, 0x02, 0x08, 0x00, 0x3f, 0x15, 0x0f, 0x02, 0x00, 0x01, + 0x82, 0xd9, 0xb1, 0x54, 0x00, 0x00, 0x00, 0x00, 0xb5, 0xe6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, +} + +func TestPacketEthernetOverGRE(t *testing.T) { + p := gopacket.NewPacket(testPacketEthernetOverGRE, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeGRE, LayerTypeEthernet, LayerTypeIPv4, LayerTypeICMPv4, gopacket.LayerTypePayload}, t) + if got, ok := p.Layer(LayerTypeGRE).(*GRE); ok { + want := &GRE{ + BaseLayer: BaseLayer{testPacketEthernetOverGRE[34:38], testPacketEthernetOverGRE[38:]}, + Protocol: EthernetTypeTransparentEthernetBridging, + } + if !reflect.DeepEqual(want, got) { + t.Errorf("GRE layer mismatch, \nwant %#v\ngot %#v\n", want, got) + } + } +} + +func BenchmarkDecodePacketEthernetOverGRE(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketEthernetOverGRE, LinkTypeEthernet, gopacket.NoCopy) + } +} + +var testEthernetOverGRE = []gopacket.SerializableLayer{ + &Ethernet{ + SrcMAC: net.HardwareAddr{0xd6, 0xb9, 0xd8, 0x80, 0x56, 0xef}, + DstMAC: net.HardwareAddr{0xea, 0x6b, 0x4c, 0xd3, 0x55, 0x13}, + EthernetType: EthernetTypeIPv4, + }, + &IPv4{ + Version: 4, + SrcIP: net.IP{192, 168, 1, 1}, + DstIP: net.IP{192, 168, 1, 2}, + Protocol: IPProtocolGRE, + Flags: IPv4DontFragment, + TTL: 64, + Id: 2765, + IHL: 5, + }, + &GRE{ + Protocol: EthernetTypeTransparentEthernetBridging, + }, + &Ethernet{ + SrcMAC: net.HardwareAddr{0x6e, 0x32, 0x3e, 0xc7, 0x9d, 0xef}, + DstMAC: net.HardwareAddr{0xaa, 0x6a, 0x36, 0xe6, 0xc6, 0x30}, + EthernetType: EthernetTypeIPv4, + }, + &IPv4{ + Version: 4, + SrcIP: net.IP{172, 16, 1, 1}, + DstIP: net.IP{172, 16, 1, 2}, + Protocol: IPProtocolICMPv4, + Flags: IPv4DontFragment, + TTL: 64, + IHL: 5, + Id: 55664, + }, + &ICMPv4{ + TypeCode: CreateICMPv4TypeCode(ICMPv4TypeEchoRequest, 0), + Id: 3842, + Seq: 1, + }, + gopacket.Payload{ + 0x82, 0xd9, 0xb1, 0x54, 0x00, 0x00, 0x00, 0x00, 0xb5, 0xe6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + }, +} + +func TestEthernetOverGREEncode(t *testing.T) { + b := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{ + ComputeChecksums: true, + FixLengths: true, + } + if err := gopacket.SerializeLayers(b, opts, testEthernetOverGRE...); err != nil { + t.Errorf("Unable to serialize: %v", err) + } + p := gopacket.NewPacket(b.Bytes(), LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeGRE, LayerTypeEthernet, LayerTypeIPv4, LayerTypeICMPv4, gopacket.LayerTypePayload}, t) + if got, want := b.Bytes(), testPacketEthernetOverGRE; !reflect.DeepEqual(want, got) { + t.Errorf("Encoding mismatch, \nwant: %v\ngot %v\n", want, got) + } +} + +func BenchmarkEncodePacketEthernetOverGRE(b *testing.B) { + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{ + ComputeChecksums: true, + FixLengths: true, + } + for i := 0; i < b.N; i++ { + gopacket.SerializeLayers(buf, opts, testEthernetOverGRE...) + buf.Clear() + } +} + +var testGREChecksum = map[uint16][]gopacket.SerializableLayer{ + 0x77ff: { + &Ethernet{ + SrcMAC: net.HardwareAddr{0xc2, 0x00, 0x57, 0x75, 0x00, 0x00}, + DstMAC: net.HardwareAddr{0xc2, 0x01, 0x57, 0x75, 0x00, 0x00}, + EthernetType: EthernetTypeIPv4, + }, + &IPv4{ + Version: 4, + SrcIP: net.IP{10, 0, 0, 1}, + DstIP: net.IP{10, 0, 0, 2}, + Protocol: IPProtocolGRE, + TTL: 255, + Id: 10, + IHL: 5, + }, + &GRE{ + Protocol: EthernetTypeIPv4, + ChecksumPresent: true, + }, + &IPv4{ + Version: 4, + SrcIP: net.IP{1, 1, 1, 1}, + DstIP: net.IP{2, 2, 2, 2}, + Protocol: IPProtocolICMPv4, + TTL: 255, + IHL: 5, + Id: 10, + }, + &ICMPv4{ + TypeCode: CreateICMPv4TypeCode(ICMPv4TypeEchoRequest, 0), + Id: 2, + Seq: 0, + }, + gopacket.Payload{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xbe, 0x70, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + }, + }, + 0x8475: { + &Ethernet{ + SrcMAC: net.HardwareAddr{0xc2, 0x00, 0x57, 0x75, 0x00, 0x00}, + DstMAC: net.HardwareAddr{0xc2, 0x01, 0x57, 0x75, 0x00, 0x00}, + EthernetType: EthernetTypeIPv4, + }, + &IPv4{ + Version: 4, + SrcIP: net.IP{10, 0, 0, 1}, + DstIP: net.IP{10, 0, 0, 2}, + Protocol: IPProtocolGRE, + TTL: 255, + Id: 10, + IHL: 5, + }, + &GRE{ + Protocol: EthernetTypeIPv4, + ChecksumPresent: true, + }, + &IPv4{ + Version: 4, + SrcIP: net.IP{2, 3, 4, 5}, + DstIP: net.IP{2, 3, 4, 50}, + Protocol: IPProtocolUDP, + TTL: 1, + IHL: 5, + Flags: IPv4DontFragment, + Id: 964, + }, + &UDP{ + SrcPort: 41781, + DstPort: 33434, + }, + gopacket.Payload{ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + }, + }, +} + +func TestGREChecksum(t *testing.T) { + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{ + ComputeChecksums: true, + FixLengths: true, + } + for cksum, packet := range testGREChecksum { + buf.Clear() + if err := setNetworkLayer(packet); err != nil { + t.Errorf("Failed to set network layer: %v", err) + continue + } + if err := gopacket.SerializeLayers(buf, opts, packet...); err != nil { + t.Errorf("Failed to serialize packet: %v", err) + continue + } + p := gopacket.NewPacket(buf.Bytes(), LinkTypeEthernet, gopacket.Default) + t.Log(p) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + continue + } + if got, ok := p.Layer(LayerTypeGRE).(*GRE); ok { + if got.Checksum != cksum { + t.Errorf("Incorrect checksum calculated for GRE packet: want %v, got %v", cksum, got.Checksum) + } + } + } +} + +func setNetworkLayer(layers []gopacket.SerializableLayer) error { + type setNetworkLayerForChecksum interface { + SetNetworkLayerForChecksum(gopacket.NetworkLayer) error + } + var l gopacket.NetworkLayer + for _, layer := range layers { + if n, ok := layer.(gopacket.NetworkLayer); ok { + l = n + } + if s, ok := layer.(setNetworkLayerForChecksum); ok { + if l == nil { + return fmt.Errorf("no enclosing network layer found before: %v", s) + } + if err := s.SetNetworkLayerForChecksum(l); err != nil { + return fmt.Errorf("failed to set network layer(%v) on layer(%v): %v", l, s, err) + } + } + } + return nil +} diff --git a/vendor/github.com/google/gopacket/layers/iana_ports.go b/vendor/github.com/google/gopacket/layers/iana_ports.go new file mode 100644 index 0000000..c217a69 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/iana_ports.go @@ -0,0 +1,11350 @@ +// Copyright 2012 Google, Inc. All rights reserved. + +package layers + +// Created by gen.go, don't edit manually +// Generated at 2017-09-19 13:08:22.987239325 -0600 MDT +// Fetched from "http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml" + +// TCPPortNames contains the port names for all TCP ports. +var TCPPortNames = tcpPortNames + +// UDPPortNames contains the port names for all UDP ports. +var UDPPortNames = udpPortNames + +// SCTPPortNames contains the port names for all SCTP ports. +var SCTPPortNames = sctpPortNames + +var tcpPortNames = map[TCPPort]string{ + 1: "tcpmux", + 2: "compressnet", + 3: "compressnet", + 5: "rje", + 7: "echo", + 9: "discard", + 11: "systat", + 13: "daytime", + 17: "qotd", + 18: "msp", + 19: "chargen", + 20: "ftp-data", + 21: "ftp", + 22: "ssh", + 23: "telnet", + 25: "smtp", + 27: "nsw-fe", + 29: "msg-icp", + 31: "msg-auth", + 33: "dsp", + 37: "time", + 38: "rap", + 39: "rlp", + 41: "graphics", + 42: "name", + 43: "nicname", + 44: "mpm-flags", + 45: "mpm", + 46: "mpm-snd", + 48: "auditd", + 49: "tacacs", + 50: "re-mail-ck", + 52: "xns-time", + 53: "domain", + 54: "xns-ch", + 55: "isi-gl", + 56: "xns-auth", + 58: "xns-mail", + 62: "acas", + 63: "whoispp", + 64: "covia", + 65: "tacacs-ds", + 66: "sql-net", + 67: "bootps", + 68: "bootpc", + 69: "tftp", + 70: "gopher", + 71: "netrjs-1", + 72: "netrjs-2", + 73: "netrjs-3", + 74: "netrjs-4", + 76: "deos", + 78: "vettcp", + 79: "finger", + 80: "http", + 82: "xfer", + 83: "mit-ml-dev", + 84: "ctf", + 85: "mit-ml-dev", + 86: "mfcobol", + 88: "kerberos", + 89: "su-mit-tg", + 90: "dnsix", + 91: "mit-dov", + 92: "npp", + 93: "dcp", + 94: "objcall", + 95: "supdup", + 96: "dixie", + 97: "swift-rvf", + 98: "tacnews", + 99: "metagram", + 101: "hostname", + 102: "iso-tsap", + 103: "gppitnp", + 104: "acr-nema", + 105: "cso", + 106: "3com-tsmux", + 107: "rtelnet", + 108: "snagas", + 109: "pop2", + 110: "pop3", + 111: "sunrpc", + 112: "mcidas", + 113: "ident", + 115: "sftp", + 116: "ansanotify", + 117: "uucp-path", + 118: "sqlserv", + 119: "nntp", + 120: "cfdptkt", + 121: "erpc", + 122: "smakynet", + 123: "ntp", + 124: "ansatrader", + 125: "locus-map", + 126: "nxedit", + 127: "locus-con", + 128: "gss-xlicen", + 129: "pwdgen", + 130: "cisco-fna", + 131: "cisco-tna", + 132: "cisco-sys", + 133: "statsrv", + 134: "ingres-net", + 135: "epmap", + 136: "profile", + 137: "netbios-ns", + 138: "netbios-dgm", + 139: "netbios-ssn", + 140: "emfis-data", + 141: "emfis-cntl", + 142: "bl-idm", + 143: "imap", + 144: "uma", + 145: "uaac", + 146: "iso-tp0", + 147: "iso-ip", + 148: "jargon", + 149: "aed-512", + 150: "sql-net", + 151: "hems", + 152: "bftp", + 153: "sgmp", + 154: "netsc-prod", + 155: "netsc-dev", + 156: "sqlsrv", + 157: "knet-cmp", + 158: "pcmail-srv", + 159: "nss-routing", + 160: "sgmp-traps", + 161: "snmp", + 162: "snmptrap", + 163: "cmip-man", + 164: "cmip-agent", + 165: "xns-courier", + 166: "s-net", + 167: "namp", + 168: "rsvd", + 169: "send", + 170: "print-srv", + 171: "multiplex", + 172: "cl-1", + 173: "xyplex-mux", + 174: "mailq", + 175: "vmnet", + 176: "genrad-mux", + 177: "xdmcp", + 178: "nextstep", + 179: "bgp", + 180: "ris", + 181: "unify", + 182: "audit", + 183: "ocbinder", + 184: "ocserver", + 185: "remote-kis", + 186: "kis", + 187: "aci", + 188: "mumps", + 189: "qft", + 190: "gacp", + 191: "prospero", + 192: "osu-nms", + 193: "srmp", + 194: "irc", + 195: "dn6-nlm-aud", + 196: "dn6-smm-red", + 197: "dls", + 198: "dls-mon", + 199: "smux", + 200: "src", + 201: "at-rtmp", + 202: "at-nbp", + 203: "at-3", + 204: "at-echo", + 205: "at-5", + 206: "at-zis", + 207: "at-7", + 208: "at-8", + 209: "qmtp", + 210: "z39-50", + 211: "914c-g", + 212: "anet", + 213: "ipx", + 214: "vmpwscs", + 215: "softpc", + 216: "CAIlic", + 217: "dbase", + 218: "mpp", + 219: "uarps", + 220: "imap3", + 221: "fln-spx", + 222: "rsh-spx", + 223: "cdc", + 224: "masqdialer", + 242: "direct", + 243: "sur-meas", + 244: "inbusiness", + 245: "link", + 246: "dsp3270", + 247: "subntbcst-tftp", + 248: "bhfhs", + 256: "rap", + 257: "set", + 259: "esro-gen", + 260: "openport", + 261: "nsiiops", + 262: "arcisdms", + 263: "hdap", + 264: "bgmp", + 265: "x-bone-ctl", + 266: "sst", + 267: "td-service", + 268: "td-replica", + 269: "manet", + 271: "pt-tls", + 280: "http-mgmt", + 281: "personal-link", + 282: "cableport-ax", + 283: "rescap", + 284: "corerjd", + 286: "fxp", + 287: "k-block", + 308: "novastorbakcup", + 309: "entrusttime", + 310: "bhmds", + 311: "asip-webadmin", + 312: "vslmp", + 313: "magenta-logic", + 314: "opalis-robot", + 315: "dpsi", + 316: "decauth", + 317: "zannet", + 318: "pkix-timestamp", + 319: "ptp-event", + 320: "ptp-general", + 321: "pip", + 322: "rtsps", + 323: "rpki-rtr", + 324: "rpki-rtr-tls", + 333: "texar", + 344: "pdap", + 345: "pawserv", + 346: "zserv", + 347: "fatserv", + 348: "csi-sgwp", + 349: "mftp", + 350: "matip-type-a", + 351: "matip-type-b", + 352: "dtag-ste-sb", + 353: "ndsauth", + 354: "bh611", + 355: "datex-asn", + 356: "cloanto-net-1", + 357: "bhevent", + 358: "shrinkwrap", + 359: "nsrmp", + 360: "scoi2odialog", + 361: "semantix", + 362: "srssend", + 363: "rsvp-tunnel", + 364: "aurora-cmgr", + 365: "dtk", + 366: "odmr", + 367: "mortgageware", + 368: "qbikgdp", + 369: "rpc2portmap", + 370: "codaauth2", + 371: "clearcase", + 372: "ulistproc", + 373: "legent-1", + 374: "legent-2", + 375: "hassle", + 376: "nip", + 377: "tnETOS", + 378: "dsETOS", + 379: "is99c", + 380: "is99s", + 381: "hp-collector", + 382: "hp-managed-node", + 383: "hp-alarm-mgr", + 384: "arns", + 385: "ibm-app", + 386: "asa", + 387: "aurp", + 388: "unidata-ldm", + 389: "ldap", + 390: "uis", + 391: "synotics-relay", + 392: "synotics-broker", + 393: "meta5", + 394: "embl-ndt", + 395: "netcp", + 396: "netware-ip", + 397: "mptn", + 398: "kryptolan", + 399: "iso-tsap-c2", + 400: "osb-sd", + 401: "ups", + 402: "genie", + 403: "decap", + 404: "nced", + 405: "ncld", + 406: "imsp", + 407: "timbuktu", + 408: "prm-sm", + 409: "prm-nm", + 410: "decladebug", + 411: "rmt", + 412: "synoptics-trap", + 413: "smsp", + 414: "infoseek", + 415: "bnet", + 416: "silverplatter", + 417: "onmux", + 418: "hyper-g", + 419: "ariel1", + 420: "smpte", + 421: "ariel2", + 422: "ariel3", + 423: "opc-job-start", + 424: "opc-job-track", + 425: "icad-el", + 426: "smartsdp", + 427: "svrloc", + 428: "ocs-cmu", + 429: "ocs-amu", + 430: "utmpsd", + 431: "utmpcd", + 432: "iasd", + 433: "nnsp", + 434: "mobileip-agent", + 435: "mobilip-mn", + 436: "dna-cml", + 437: "comscm", + 438: "dsfgw", + 439: "dasp", + 440: "sgcp", + 441: "decvms-sysmgt", + 442: "cvc-hostd", + 443: "https", + 444: "snpp", + 445: "microsoft-ds", + 446: "ddm-rdb", + 447: "ddm-dfm", + 448: "ddm-ssl", + 449: "as-servermap", + 450: "tserver", + 451: "sfs-smp-net", + 452: "sfs-config", + 453: "creativeserver", + 454: "contentserver", + 455: "creativepartnr", + 456: "macon-tcp", + 457: "scohelp", + 458: "appleqtc", + 459: "ampr-rcmd", + 460: "skronk", + 461: "datasurfsrv", + 462: "datasurfsrvsec", + 463: "alpes", + 464: "kpasswd", + 465: "urd", + 466: "digital-vrc", + 467: "mylex-mapd", + 468: "photuris", + 469: "rcp", + 470: "scx-proxy", + 471: "mondex", + 472: "ljk-login", + 473: "hybrid-pop", + 474: "tn-tl-w1", + 475: "tcpnethaspsrv", + 476: "tn-tl-fd1", + 477: "ss7ns", + 478: "spsc", + 479: "iafserver", + 480: "iafdbase", + 481: "ph", + 482: "bgs-nsi", + 483: "ulpnet", + 484: "integra-sme", + 485: "powerburst", + 486: "avian", + 487: "saft", + 488: "gss-http", + 489: "nest-protocol", + 490: "micom-pfs", + 491: "go-login", + 492: "ticf-1", + 493: "ticf-2", + 494: "pov-ray", + 495: "intecourier", + 496: "pim-rp-disc", + 497: "retrospect", + 498: "siam", + 499: "iso-ill", + 500: "isakmp", + 501: "stmf", + 502: "mbap", + 503: "intrinsa", + 504: "citadel", + 505: "mailbox-lm", + 506: "ohimsrv", + 507: "crs", + 508: "xvttp", + 509: "snare", + 510: "fcp", + 511: "passgo", + 512: "exec", + 513: "login", + 514: "shell", + 515: "printer", + 516: "videotex", + 517: "talk", + 518: "ntalk", + 519: "utime", + 520: "efs", + 521: "ripng", + 522: "ulp", + 523: "ibm-db2", + 524: "ncp", + 525: "timed", + 526: "tempo", + 527: "stx", + 528: "custix", + 529: "irc-serv", + 530: "courier", + 531: "conference", + 532: "netnews", + 533: "netwall", + 534: "windream", + 535: "iiop", + 536: "opalis-rdv", + 537: "nmsp", + 538: "gdomap", + 539: "apertus-ldp", + 540: "uucp", + 541: "uucp-rlogin", + 542: "commerce", + 543: "klogin", + 544: "kshell", + 545: "appleqtcsrvr", + 546: "dhcpv6-client", + 547: "dhcpv6-server", + 548: "afpovertcp", + 549: "idfp", + 550: "new-rwho", + 551: "cybercash", + 552: "devshr-nts", + 553: "pirp", + 554: "rtsp", + 555: "dsf", + 556: "remotefs", + 557: "openvms-sysipc", + 558: "sdnskmp", + 559: "teedtap", + 560: "rmonitor", + 561: "monitor", + 562: "chshell", + 563: "nntps", + 564: "9pfs", + 565: "whoami", + 566: "streettalk", + 567: "banyan-rpc", + 568: "ms-shuttle", + 569: "ms-rome", + 570: "meter", + 571: "meter", + 572: "sonar", + 573: "banyan-vip", + 574: "ftp-agent", + 575: "vemmi", + 576: "ipcd", + 577: "vnas", + 578: "ipdd", + 579: "decbsrv", + 580: "sntp-heartbeat", + 581: "bdp", + 582: "scc-security", + 583: "philips-vc", + 584: "keyserver", + 586: "password-chg", + 587: "submission", + 588: "cal", + 589: "eyelink", + 590: "tns-cml", + 591: "http-alt", + 592: "eudora-set", + 593: "http-rpc-epmap", + 594: "tpip", + 595: "cab-protocol", + 596: "smsd", + 597: "ptcnameservice", + 598: "sco-websrvrmg3", + 599: "acp", + 600: "ipcserver", + 601: "syslog-conn", + 602: "xmlrpc-beep", + 603: "idxp", + 604: "tunnel", + 605: "soap-beep", + 606: "urm", + 607: "nqs", + 608: "sift-uft", + 609: "npmp-trap", + 610: "npmp-local", + 611: "npmp-gui", + 612: "hmmp-ind", + 613: "hmmp-op", + 614: "sshell", + 615: "sco-inetmgr", + 616: "sco-sysmgr", + 617: "sco-dtmgr", + 618: "dei-icda", + 619: "compaq-evm", + 620: "sco-websrvrmgr", + 621: "escp-ip", + 622: "collaborator", + 623: "oob-ws-http", + 624: "cryptoadmin", + 625: "dec-dlm", + 626: "asia", + 627: "passgo-tivoli", + 628: "qmqp", + 629: "3com-amp3", + 630: "rda", + 631: "ipp", + 632: "bmpp", + 633: "servstat", + 634: "ginad", + 635: "rlzdbase", + 636: "ldaps", + 637: "lanserver", + 638: "mcns-sec", + 639: "msdp", + 640: "entrust-sps", + 641: "repcmd", + 642: "esro-emsdp", + 643: "sanity", + 644: "dwr", + 645: "pssc", + 646: "ldp", + 647: "dhcp-failover", + 648: "rrp", + 649: "cadview-3d", + 650: "obex", + 651: "ieee-mms", + 652: "hello-port", + 653: "repscmd", + 654: "aodv", + 655: "tinc", + 656: "spmp", + 657: "rmc", + 658: "tenfold", + 660: "mac-srvr-admin", + 661: "hap", + 662: "pftp", + 663: "purenoise", + 664: "oob-ws-https", + 665: "sun-dr", + 666: "mdqs", + 667: "disclose", + 668: "mecomm", + 669: "meregister", + 670: "vacdsm-sws", + 671: "vacdsm-app", + 672: "vpps-qua", + 673: "cimplex", + 674: "acap", + 675: "dctp", + 676: "vpps-via", + 677: "vpp", + 678: "ggf-ncp", + 679: "mrm", + 680: "entrust-aaas", + 681: "entrust-aams", + 682: "xfr", + 683: "corba-iiop", + 684: "corba-iiop-ssl", + 685: "mdc-portmapper", + 686: "hcp-wismar", + 687: "asipregistry", + 688: "realm-rusd", + 689: "nmap", + 690: "vatp", + 691: "msexch-routing", + 692: "hyperwave-isp", + 693: "connendp", + 694: "ha-cluster", + 695: "ieee-mms-ssl", + 696: "rushd", + 697: "uuidgen", + 698: "olsr", + 699: "accessnetwork", + 700: "epp", + 701: "lmp", + 702: "iris-beep", + 704: "elcsd", + 705: "agentx", + 706: "silc", + 707: "borland-dsj", + 709: "entrust-kmsh", + 710: "entrust-ash", + 711: "cisco-tdp", + 712: "tbrpf", + 713: "iris-xpc", + 714: "iris-xpcs", + 715: "iris-lwz", + 729: "netviewdm1", + 730: "netviewdm2", + 731: "netviewdm3", + 741: "netgw", + 742: "netrcs", + 744: "flexlm", + 747: "fujitsu-dev", + 748: "ris-cm", + 749: "kerberos-adm", + 750: "rfile", + 751: "pump", + 752: "qrh", + 753: "rrh", + 754: "tell", + 758: "nlogin", + 759: "con", + 760: "ns", + 761: "rxe", + 762: "quotad", + 763: "cycleserv", + 764: "omserv", + 765: "webster", + 767: "phonebook", + 769: "vid", + 770: "cadlock", + 771: "rtip", + 772: "cycleserv2", + 773: "submit", + 774: "rpasswd", + 775: "entomb", + 776: "wpages", + 777: "multiling-http", + 780: "wpgs", + 800: "mdbs-daemon", + 801: "device", + 802: "mbap-s", + 810: "fcp-udp", + 828: "itm-mcell-s", + 829: "pkix-3-ca-ra", + 830: "netconf-ssh", + 831: "netconf-beep", + 832: "netconfsoaphttp", + 833: "netconfsoapbeep", + 847: "dhcp-failover2", + 848: "gdoi", + 853: "domain-s", + 854: "dlep", + 860: "iscsi", + 861: "owamp-control", + 862: "twamp-control", + 873: "rsync", + 886: "iclcnet-locate", + 887: "iclcnet-svinfo", + 888: "accessbuilder", + 900: "omginitialrefs", + 901: "smpnameres", + 902: "ideafarm-door", + 903: "ideafarm-panic", + 910: "kink", + 911: "xact-backup", + 912: "apex-mesh", + 913: "apex-edge", + 953: "rndc", + 989: "ftps-data", + 990: "ftps", + 991: "nas", + 992: "telnets", + 993: "imaps", + 995: "pop3s", + 996: "vsinet", + 997: "maitrd", + 998: "busboy", + 999: "garcon", + 1000: "cadlock2", + 1001: "webpush", + 1010: "surf", + 1021: "exp1", + 1022: "exp2", + 1025: "blackjack", + 1026: "cap", + 1029: "solid-mux", + 1033: "netinfo-local", + 1034: "activesync", + 1035: "mxxrlogin", + 1036: "nsstp", + 1037: "ams", + 1038: "mtqp", + 1039: "sbl", + 1040: "netarx", + 1041: "danf-ak2", + 1042: "afrog", + 1043: "boinc-client", + 1044: "dcutility", + 1045: "fpitp", + 1046: "wfremotertm", + 1047: "neod1", + 1048: "neod2", + 1049: "td-postman", + 1050: "cma", + 1051: "optima-vnet", + 1052: "ddt", + 1053: "remote-as", + 1054: "brvread", + 1055: "ansyslmd", + 1056: "vfo", + 1057: "startron", + 1058: "nim", + 1059: "nimreg", + 1060: "polestar", + 1061: "kiosk", + 1062: "veracity", + 1063: "kyoceranetdev", + 1064: "jstel", + 1065: "syscomlan", + 1066: "fpo-fns", + 1067: "instl-boots", + 1068: "instl-bootc", + 1069: "cognex-insight", + 1070: "gmrupdateserv", + 1071: "bsquare-voip", + 1072: "cardax", + 1073: "bridgecontrol", + 1074: "warmspotMgmt", + 1075: "rdrmshc", + 1076: "dab-sti-c", + 1077: "imgames", + 1078: "avocent-proxy", + 1079: "asprovatalk", + 1080: "socks", + 1081: "pvuniwien", + 1082: "amt-esd-prot", + 1083: "ansoft-lm-1", + 1084: "ansoft-lm-2", + 1085: "webobjects", + 1086: "cplscrambler-lg", + 1087: "cplscrambler-in", + 1088: "cplscrambler-al", + 1089: "ff-annunc", + 1090: "ff-fms", + 1091: "ff-sm", + 1092: "obrpd", + 1093: "proofd", + 1094: "rootd", + 1095: "nicelink", + 1096: "cnrprotocol", + 1097: "sunclustermgr", + 1098: "rmiactivation", + 1099: "rmiregistry", + 1100: "mctp", + 1101: "pt2-discover", + 1102: "adobeserver-1", + 1103: "adobeserver-2", + 1104: "xrl", + 1105: "ftranhc", + 1106: "isoipsigport-1", + 1107: "isoipsigport-2", + 1108: "ratio-adp", + 1110: "webadmstart", + 1111: "lmsocialserver", + 1112: "icp", + 1113: "ltp-deepspace", + 1114: "mini-sql", + 1115: "ardus-trns", + 1116: "ardus-cntl", + 1117: "ardus-mtrns", + 1118: "sacred", + 1119: "bnetgame", + 1120: "bnetfile", + 1121: "rmpp", + 1122: "availant-mgr", + 1123: "murray", + 1124: "hpvmmcontrol", + 1125: "hpvmmagent", + 1126: "hpvmmdata", + 1127: "kwdb-commn", + 1128: "saphostctrl", + 1129: "saphostctrls", + 1130: "casp", + 1131: "caspssl", + 1132: "kvm-via-ip", + 1133: "dfn", + 1134: "aplx", + 1135: "omnivision", + 1136: "hhb-gateway", + 1137: "trim", + 1138: "encrypted-admin", + 1139: "evm", + 1140: "autonoc", + 1141: "mxomss", + 1142: "edtools", + 1143: "imyx", + 1144: "fuscript", + 1145: "x9-icue", + 1146: "audit-transfer", + 1147: "capioverlan", + 1148: "elfiq-repl", + 1149: "bvtsonar", + 1150: "blaze", + 1151: "unizensus", + 1152: "winpoplanmess", + 1153: "c1222-acse", + 1154: "resacommunity", + 1155: "nfa", + 1156: "iascontrol-oms", + 1157: "iascontrol", + 1158: "dbcontrol-oms", + 1159: "oracle-oms", + 1160: "olsv", + 1161: "health-polling", + 1162: "health-trap", + 1163: "sddp", + 1164: "qsm-proxy", + 1165: "qsm-gui", + 1166: "qsm-remote", + 1167: "cisco-ipsla", + 1168: "vchat", + 1169: "tripwire", + 1170: "atc-lm", + 1171: "atc-appserver", + 1172: "dnap", + 1173: "d-cinema-rrp", + 1174: "fnet-remote-ui", + 1175: "dossier", + 1176: "indigo-server", + 1177: "dkmessenger", + 1178: "sgi-storman", + 1179: "b2n", + 1180: "mc-client", + 1181: "3comnetman", + 1182: "accelenet", + 1183: "llsurfup-http", + 1184: "llsurfup-https", + 1185: "catchpole", + 1186: "mysql-cluster", + 1187: "alias", + 1188: "hp-webadmin", + 1189: "unet", + 1190: "commlinx-avl", + 1191: "gpfs", + 1192: "caids-sensor", + 1193: "fiveacross", + 1194: "openvpn", + 1195: "rsf-1", + 1196: "netmagic", + 1197: "carrius-rshell", + 1198: "cajo-discovery", + 1199: "dmidi", + 1200: "scol", + 1201: "nucleus-sand", + 1202: "caiccipc", + 1203: "ssslic-mgr", + 1204: "ssslog-mgr", + 1205: "accord-mgc", + 1206: "anthony-data", + 1207: "metasage", + 1208: "seagull-ais", + 1209: "ipcd3", + 1210: "eoss", + 1211: "groove-dpp", + 1212: "lupa", + 1213: "mpc-lifenet", + 1214: "kazaa", + 1215: "scanstat-1", + 1216: "etebac5", + 1217: "hpss-ndapi", + 1218: "aeroflight-ads", + 1219: "aeroflight-ret", + 1220: "qt-serveradmin", + 1221: "sweetware-apps", + 1222: "nerv", + 1223: "tgp", + 1224: "vpnz", + 1225: "slinkysearch", + 1226: "stgxfws", + 1227: "dns2go", + 1228: "florence", + 1229: "zented", + 1230: "periscope", + 1231: "menandmice-lpm", + 1232: "first-defense", + 1233: "univ-appserver", + 1234: "search-agent", + 1235: "mosaicsyssvc1", + 1236: "bvcontrol", + 1237: "tsdos390", + 1238: "hacl-qs", + 1239: "nmsd", + 1240: "instantia", + 1241: "nessus", + 1242: "nmasoverip", + 1243: "serialgateway", + 1244: "isbconference1", + 1245: "isbconference2", + 1246: "payrouter", + 1247: "visionpyramid", + 1248: "hermes", + 1249: "mesavistaco", + 1250: "swldy-sias", + 1251: "servergraph", + 1252: "bspne-pcc", + 1253: "q55-pcc", + 1254: "de-noc", + 1255: "de-cache-query", + 1256: "de-server", + 1257: "shockwave2", + 1258: "opennl", + 1259: "opennl-voice", + 1260: "ibm-ssd", + 1261: "mpshrsv", + 1262: "qnts-orb", + 1263: "dka", + 1264: "prat", + 1265: "dssiapi", + 1266: "dellpwrappks", + 1267: "epc", + 1268: "propel-msgsys", + 1269: "watilapp", + 1270: "opsmgr", + 1271: "excw", + 1272: "cspmlockmgr", + 1273: "emc-gateway", + 1274: "t1distproc", + 1275: "ivcollector", + 1277: "miva-mqs", + 1278: "dellwebadmin-1", + 1279: "dellwebadmin-2", + 1280: "pictrography", + 1281: "healthd", + 1282: "emperion", + 1283: "productinfo", + 1284: "iee-qfx", + 1285: "neoiface", + 1286: "netuitive", + 1287: "routematch", + 1288: "navbuddy", + 1289: "jwalkserver", + 1290: "winjaserver", + 1291: "seagulllms", + 1292: "dsdn", + 1293: "pkt-krb-ipsec", + 1294: "cmmdriver", + 1295: "ehtp", + 1296: "dproxy", + 1297: "sdproxy", + 1298: "lpcp", + 1299: "hp-sci", + 1300: "h323hostcallsc", + 1301: "ci3-software-1", + 1302: "ci3-software-2", + 1303: "sftsrv", + 1304: "boomerang", + 1305: "pe-mike", + 1306: "re-conn-proto", + 1307: "pacmand", + 1308: "odsi", + 1309: "jtag-server", + 1310: "husky", + 1311: "rxmon", + 1312: "sti-envision", + 1313: "bmc-patroldb", + 1314: "pdps", + 1315: "els", + 1316: "exbit-escp", + 1317: "vrts-ipcserver", + 1318: "krb5gatekeeper", + 1319: "amx-icsp", + 1320: "amx-axbnet", + 1321: "pip", + 1322: "novation", + 1323: "brcd", + 1324: "delta-mcp", + 1325: "dx-instrument", + 1326: "wimsic", + 1327: "ultrex", + 1328: "ewall", + 1329: "netdb-export", + 1330: "streetperfect", + 1331: "intersan", + 1332: "pcia-rxp-b", + 1333: "passwrd-policy", + 1334: "writesrv", + 1335: "digital-notary", + 1336: "ischat", + 1337: "menandmice-dns", + 1338: "wmc-log-svc", + 1339: "kjtsiteserver", + 1340: "naap", + 1341: "qubes", + 1342: "esbroker", + 1343: "re101", + 1344: "icap", + 1345: "vpjp", + 1346: "alta-ana-lm", + 1347: "bbn-mmc", + 1348: "bbn-mmx", + 1349: "sbook", + 1350: "editbench", + 1351: "equationbuilder", + 1352: "lotusnote", + 1353: "relief", + 1354: "XSIP-network", + 1355: "intuitive-edge", + 1356: "cuillamartin", + 1357: "pegboard", + 1358: "connlcli", + 1359: "ftsrv", + 1360: "mimer", + 1361: "linx", + 1362: "timeflies", + 1363: "ndm-requester", + 1364: "ndm-server", + 1365: "adapt-sna", + 1366: "netware-csp", + 1367: "dcs", + 1368: "screencast", + 1369: "gv-us", + 1370: "us-gv", + 1371: "fc-cli", + 1372: "fc-ser", + 1373: "chromagrafx", + 1374: "molly", + 1375: "bytex", + 1376: "ibm-pps", + 1377: "cichlid", + 1378: "elan", + 1379: "dbreporter", + 1380: "telesis-licman", + 1381: "apple-licman", + 1382: "udt-os", + 1383: "gwha", + 1384: "os-licman", + 1385: "atex-elmd", + 1386: "checksum", + 1387: "cadsi-lm", + 1388: "objective-dbc", + 1389: "iclpv-dm", + 1390: "iclpv-sc", + 1391: "iclpv-sas", + 1392: "iclpv-pm", + 1393: "iclpv-nls", + 1394: "iclpv-nlc", + 1395: "iclpv-wsm", + 1396: "dvl-activemail", + 1397: "audio-activmail", + 1398: "video-activmail", + 1399: "cadkey-licman", + 1400: "cadkey-tablet", + 1401: "goldleaf-licman", + 1402: "prm-sm-np", + 1403: "prm-nm-np", + 1404: "igi-lm", + 1405: "ibm-res", + 1406: "netlabs-lm", + 1407: "tibet-server", + 1408: "sophia-lm", + 1409: "here-lm", + 1410: "hiq", + 1411: "af", + 1412: "innosys", + 1413: "innosys-acl", + 1414: "ibm-mqseries", + 1415: "dbstar", + 1416: "novell-lu6-2", + 1417: "timbuktu-srv1", + 1418: "timbuktu-srv2", + 1419: "timbuktu-srv3", + 1420: "timbuktu-srv4", + 1421: "gandalf-lm", + 1422: "autodesk-lm", + 1423: "essbase", + 1424: "hybrid", + 1425: "zion-lm", + 1426: "sais", + 1427: "mloadd", + 1428: "informatik-lm", + 1429: "nms", + 1430: "tpdu", + 1431: "rgtp", + 1432: "blueberry-lm", + 1433: "ms-sql-s", + 1434: "ms-sql-m", + 1435: "ibm-cics", + 1436: "saism", + 1437: "tabula", + 1438: "eicon-server", + 1439: "eicon-x25", + 1440: "eicon-slp", + 1441: "cadis-1", + 1442: "cadis-2", + 1443: "ies-lm", + 1444: "marcam-lm", + 1445: "proxima-lm", + 1446: "ora-lm", + 1447: "apri-lm", + 1448: "oc-lm", + 1449: "peport", + 1450: "dwf", + 1451: "infoman", + 1452: "gtegsc-lm", + 1453: "genie-lm", + 1454: "interhdl-elmd", + 1455: "esl-lm", + 1456: "dca", + 1457: "valisys-lm", + 1458: "nrcabq-lm", + 1459: "proshare1", + 1460: "proshare2", + 1461: "ibm-wrless-lan", + 1462: "world-lm", + 1463: "nucleus", + 1464: "msl-lmd", + 1465: "pipes", + 1466: "oceansoft-lm", + 1467: "csdmbase", + 1468: "csdm", + 1469: "aal-lm", + 1470: "uaiact", + 1471: "csdmbase", + 1472: "csdm", + 1473: "openmath", + 1474: "telefinder", + 1475: "taligent-lm", + 1476: "clvm-cfg", + 1477: "ms-sna-server", + 1478: "ms-sna-base", + 1479: "dberegister", + 1480: "pacerforum", + 1481: "airs", + 1482: "miteksys-lm", + 1483: "afs", + 1484: "confluent", + 1485: "lansource", + 1486: "nms-topo-serv", + 1487: "localinfosrvr", + 1488: "docstor", + 1489: "dmdocbroker", + 1490: "insitu-conf", + 1492: "stone-design-1", + 1493: "netmap-lm", + 1494: "ica", + 1495: "cvc", + 1496: "liberty-lm", + 1497: "rfx-lm", + 1498: "sybase-sqlany", + 1499: "fhc", + 1500: "vlsi-lm", + 1501: "saiscm", + 1502: "shivadiscovery", + 1503: "imtc-mcs", + 1504: "evb-elm", + 1505: "funkproxy", + 1506: "utcd", + 1507: "symplex", + 1508: "diagmond", + 1509: "robcad-lm", + 1510: "mvx-lm", + 1511: "3l-l1", + 1512: "wins", + 1513: "fujitsu-dtc", + 1514: "fujitsu-dtcns", + 1515: "ifor-protocol", + 1516: "vpad", + 1517: "vpac", + 1518: "vpvd", + 1519: "vpvc", + 1520: "atm-zip-office", + 1521: "ncube-lm", + 1522: "ricardo-lm", + 1523: "cichild-lm", + 1524: "ingreslock", + 1525: "orasrv", + 1526: "pdap-np", + 1527: "tlisrv", + 1529: "coauthor", + 1530: "rap-service", + 1531: "rap-listen", + 1532: "miroconnect", + 1533: "virtual-places", + 1534: "micromuse-lm", + 1535: "ampr-info", + 1536: "ampr-inter", + 1537: "sdsc-lm", + 1538: "3ds-lm", + 1539: "intellistor-lm", + 1540: "rds", + 1541: "rds2", + 1542: "gridgen-elmd", + 1543: "simba-cs", + 1544: "aspeclmd", + 1545: "vistium-share", + 1546: "abbaccuray", + 1547: "laplink", + 1548: "axon-lm", + 1549: "shivahose", + 1550: "3m-image-lm", + 1551: "hecmtl-db", + 1552: "pciarray", + 1553: "sna-cs", + 1554: "caci-lm", + 1555: "livelan", + 1556: "veritas-pbx", + 1557: "arbortext-lm", + 1558: "xingmpeg", + 1559: "web2host", + 1560: "asci-val", + 1561: "facilityview", + 1562: "pconnectmgr", + 1563: "cadabra-lm", + 1564: "pay-per-view", + 1565: "winddlb", + 1566: "corelvideo", + 1567: "jlicelmd", + 1568: "tsspmap", + 1569: "ets", + 1570: "orbixd", + 1571: "rdb-dbs-disp", + 1572: "chip-lm", + 1573: "itscomm-ns", + 1574: "mvel-lm", + 1575: "oraclenames", + 1576: "moldflow-lm", + 1577: "hypercube-lm", + 1578: "jacobus-lm", + 1579: "ioc-sea-lm", + 1580: "tn-tl-r1", + 1581: "mil-2045-47001", + 1582: "msims", + 1583: "simbaexpress", + 1584: "tn-tl-fd2", + 1585: "intv", + 1586: "ibm-abtact", + 1587: "pra-elmd", + 1588: "triquest-lm", + 1589: "vqp", + 1590: "gemini-lm", + 1591: "ncpm-pm", + 1592: "commonspace", + 1593: "mainsoft-lm", + 1594: "sixtrak", + 1595: "radio", + 1596: "radio-sm", + 1597: "orbplus-iiop", + 1598: "picknfs", + 1599: "simbaservices", + 1600: "issd", + 1601: "aas", + 1602: "inspect", + 1603: "picodbc", + 1604: "icabrowser", + 1605: "slp", + 1606: "slm-api", + 1607: "stt", + 1608: "smart-lm", + 1609: "isysg-lm", + 1610: "taurus-wh", + 1611: "ill", + 1612: "netbill-trans", + 1613: "netbill-keyrep", + 1614: "netbill-cred", + 1615: "netbill-auth", + 1616: "netbill-prod", + 1617: "nimrod-agent", + 1618: "skytelnet", + 1619: "xs-openstorage", + 1620: "faxportwinport", + 1621: "softdataphone", + 1622: "ontime", + 1623: "jaleosnd", + 1624: "udp-sr-port", + 1625: "svs-omagent", + 1626: "shockwave", + 1627: "t128-gateway", + 1628: "lontalk-norm", + 1629: "lontalk-urgnt", + 1630: "oraclenet8cman", + 1631: "visitview", + 1632: "pammratc", + 1633: "pammrpc", + 1634: "loaprobe", + 1635: "edb-server1", + 1636: "isdc", + 1637: "islc", + 1638: "ismc", + 1639: "cert-initiator", + 1640: "cert-responder", + 1641: "invision", + 1642: "isis-am", + 1643: "isis-ambc", + 1644: "saiseh", + 1645: "sightline", + 1646: "sa-msg-port", + 1647: "rsap", + 1648: "concurrent-lm", + 1649: "kermit", + 1650: "nkd", + 1651: "shiva-confsrvr", + 1652: "xnmp", + 1653: "alphatech-lm", + 1654: "stargatealerts", + 1655: "dec-mbadmin", + 1656: "dec-mbadmin-h", + 1657: "fujitsu-mmpdc", + 1658: "sixnetudr", + 1659: "sg-lm", + 1660: "skip-mc-gikreq", + 1661: "netview-aix-1", + 1662: "netview-aix-2", + 1663: "netview-aix-3", + 1664: "netview-aix-4", + 1665: "netview-aix-5", + 1666: "netview-aix-6", + 1667: "netview-aix-7", + 1668: "netview-aix-8", + 1669: "netview-aix-9", + 1670: "netview-aix-10", + 1671: "netview-aix-11", + 1672: "netview-aix-12", + 1673: "proshare-mc-1", + 1674: "proshare-mc-2", + 1675: "pdp", + 1676: "netcomm1", + 1677: "groupwise", + 1678: "prolink", + 1679: "darcorp-lm", + 1680: "microcom-sbp", + 1681: "sd-elmd", + 1682: "lanyon-lantern", + 1683: "ncpm-hip", + 1684: "snaresecure", + 1685: "n2nremote", + 1686: "cvmon", + 1687: "nsjtp-ctrl", + 1688: "nsjtp-data", + 1689: "firefox", + 1690: "ng-umds", + 1691: "empire-empuma", + 1692: "sstsys-lm", + 1693: "rrirtr", + 1694: "rrimwm", + 1695: "rrilwm", + 1696: "rrifmm", + 1697: "rrisat", + 1698: "rsvp-encap-1", + 1699: "rsvp-encap-2", + 1700: "mps-raft", + 1701: "l2f", + 1702: "deskshare", + 1703: "hb-engine", + 1704: "bcs-broker", + 1705: "slingshot", + 1706: "jetform", + 1707: "vdmplay", + 1708: "gat-lmd", + 1709: "centra", + 1710: "impera", + 1711: "pptconference", + 1712: "registrar", + 1713: "conferencetalk", + 1714: "sesi-lm", + 1715: "houdini-lm", + 1716: "xmsg", + 1717: "fj-hdnet", + 1718: "h323gatedisc", + 1719: "h323gatestat", + 1720: "h323hostcall", + 1721: "caicci", + 1722: "hks-lm", + 1723: "pptp", + 1724: "csbphonemaster", + 1725: "iden-ralp", + 1726: "iberiagames", + 1727: "winddx", + 1728: "telindus", + 1729: "citynl", + 1730: "roketz", + 1731: "msiccp", + 1732: "proxim", + 1733: "siipat", + 1734: "cambertx-lm", + 1735: "privatechat", + 1736: "street-stream", + 1737: "ultimad", + 1738: "gamegen1", + 1739: "webaccess", + 1740: "encore", + 1741: "cisco-net-mgmt", + 1742: "3Com-nsd", + 1743: "cinegrfx-lm", + 1744: "ncpm-ft", + 1745: "remote-winsock", + 1746: "ftrapid-1", + 1747: "ftrapid-2", + 1748: "oracle-em1", + 1749: "aspen-services", + 1750: "sslp", + 1751: "swiftnet", + 1752: "lofr-lm", + 1753: "predatar-comms", + 1754: "oracle-em2", + 1755: "ms-streaming", + 1756: "capfast-lmd", + 1757: "cnhrp", + 1758: "tftp-mcast", + 1759: "spss-lm", + 1760: "www-ldap-gw", + 1761: "cft-0", + 1762: "cft-1", + 1763: "cft-2", + 1764: "cft-3", + 1765: "cft-4", + 1766: "cft-5", + 1767: "cft-6", + 1768: "cft-7", + 1769: "bmc-net-adm", + 1770: "bmc-net-svc", + 1771: "vaultbase", + 1772: "essweb-gw", + 1773: "kmscontrol", + 1774: "global-dtserv", + 1775: "vdab", + 1776: "femis", + 1777: "powerguardian", + 1778: "prodigy-intrnet", + 1779: "pharmasoft", + 1780: "dpkeyserv", + 1781: "answersoft-lm", + 1782: "hp-hcip", + 1784: "finle-lm", + 1785: "windlm", + 1786: "funk-logger", + 1787: "funk-license", + 1788: "psmond", + 1789: "hello", + 1790: "nmsp", + 1791: "ea1", + 1792: "ibm-dt-2", + 1793: "rsc-robot", + 1794: "cera-bcm", + 1795: "dpi-proxy", + 1796: "vocaltec-admin", + 1797: "uma", + 1798: "etp", + 1799: "netrisk", + 1800: "ansys-lm", + 1801: "msmq", + 1802: "concomp1", + 1803: "hp-hcip-gwy", + 1804: "enl", + 1805: "enl-name", + 1806: "musiconline", + 1807: "fhsp", + 1808: "oracle-vp2", + 1809: "oracle-vp1", + 1810: "jerand-lm", + 1811: "scientia-sdb", + 1812: "radius", + 1813: "radius-acct", + 1814: "tdp-suite", + 1815: "mmpft", + 1816: "harp", + 1817: "rkb-oscs", + 1818: "etftp", + 1819: "plato-lm", + 1820: "mcagent", + 1821: "donnyworld", + 1822: "es-elmd", + 1823: "unisys-lm", + 1824: "metrics-pas", + 1825: "direcpc-video", + 1826: "ardt", + 1827: "asi", + 1828: "itm-mcell-u", + 1829: "optika-emedia", + 1830: "net8-cman", + 1831: "myrtle", + 1832: "tht-treasure", + 1833: "udpradio", + 1834: "ardusuni", + 1835: "ardusmul", + 1836: "ste-smsc", + 1837: "csoft1", + 1838: "talnet", + 1839: "netopia-vo1", + 1840: "netopia-vo2", + 1841: "netopia-vo3", + 1842: "netopia-vo4", + 1843: "netopia-vo5", + 1844: "direcpc-dll", + 1845: "altalink", + 1846: "tunstall-pnc", + 1847: "slp-notify", + 1848: "fjdocdist", + 1849: "alpha-sms", + 1850: "gsi", + 1851: "ctcd", + 1852: "virtual-time", + 1853: "vids-avtp", + 1854: "buddy-draw", + 1855: "fiorano-rtrsvc", + 1856: "fiorano-msgsvc", + 1857: "datacaptor", + 1858: "privateark", + 1859: "gammafetchsvr", + 1860: "sunscalar-svc", + 1861: "lecroy-vicp", + 1862: "mysql-cm-agent", + 1863: "msnp", + 1864: "paradym-31port", + 1865: "entp", + 1866: "swrmi", + 1867: "udrive", + 1868: "viziblebrowser", + 1869: "transact", + 1870: "sunscalar-dns", + 1871: "canocentral0", + 1872: "canocentral1", + 1873: "fjmpjps", + 1874: "fjswapsnp", + 1875: "westell-stats", + 1876: "ewcappsrv", + 1877: "hp-webqosdb", + 1878: "drmsmc", + 1879: "nettgain-nms", + 1880: "vsat-control", + 1881: "ibm-mqseries2", + 1882: "ecsqdmn", + 1883: "mqtt", + 1884: "idmaps", + 1885: "vrtstrapserver", + 1886: "leoip", + 1887: "filex-lport", + 1888: "ncconfig", + 1889: "unify-adapter", + 1890: "wilkenlistener", + 1891: "childkey-notif", + 1892: "childkey-ctrl", + 1893: "elad", + 1894: "o2server-port", + 1896: "b-novative-ls", + 1897: "metaagent", + 1898: "cymtec-port", + 1899: "mc2studios", + 1900: "ssdp", + 1901: "fjicl-tep-a", + 1902: "fjicl-tep-b", + 1903: "linkname", + 1904: "fjicl-tep-c", + 1905: "sugp", + 1906: "tpmd", + 1907: "intrastar", + 1908: "dawn", + 1909: "global-wlink", + 1910: "ultrabac", + 1911: "mtp", + 1912: "rhp-iibp", + 1913: "armadp", + 1914: "elm-momentum", + 1915: "facelink", + 1916: "persona", + 1917: "noagent", + 1918: "can-nds", + 1919: "can-dch", + 1920: "can-ferret", + 1921: "noadmin", + 1922: "tapestry", + 1923: "spice", + 1924: "xiip", + 1925: "discovery-port", + 1926: "egs", + 1927: "videte-cipc", + 1928: "emsd-port", + 1929: "bandwiz-system", + 1930: "driveappserver", + 1931: "amdsched", + 1932: "ctt-broker", + 1933: "xmapi", + 1934: "xaapi", + 1935: "macromedia-fcs", + 1936: "jetcmeserver", + 1937: "jwserver", + 1938: "jwclient", + 1939: "jvserver", + 1940: "jvclient", + 1941: "dic-aida", + 1942: "res", + 1943: "beeyond-media", + 1944: "close-combat", + 1945: "dialogic-elmd", + 1946: "tekpls", + 1947: "sentinelsrm", + 1948: "eye2eye", + 1949: "ismaeasdaqlive", + 1950: "ismaeasdaqtest", + 1951: "bcs-lmserver", + 1952: "mpnjsc", + 1953: "rapidbase", + 1954: "abr-api", + 1955: "abr-secure", + 1956: "vrtl-vmf-ds", + 1957: "unix-status", + 1958: "dxadmind", + 1959: "simp-all", + 1960: "nasmanager", + 1961: "bts-appserver", + 1962: "biap-mp", + 1963: "webmachine", + 1964: "solid-e-engine", + 1965: "tivoli-npm", + 1966: "slush", + 1967: "sns-quote", + 1968: "lipsinc", + 1969: "lipsinc1", + 1970: "netop-rc", + 1971: "netop-school", + 1972: "intersys-cache", + 1973: "dlsrap", + 1974: "drp", + 1975: "tcoflashagent", + 1976: "tcoregagent", + 1977: "tcoaddressbook", + 1978: "unisql", + 1979: "unisql-java", + 1980: "pearldoc-xact", + 1981: "p2pq", + 1982: "estamp", + 1983: "lhtp", + 1984: "bb", + 1985: "hsrp", + 1986: "licensedaemon", + 1987: "tr-rsrb-p1", + 1988: "tr-rsrb-p2", + 1989: "tr-rsrb-p3", + 1990: "stun-p1", + 1991: "stun-p2", + 1992: "stun-p3", + 1993: "snmp-tcp-port", + 1994: "stun-port", + 1995: "perf-port", + 1996: "tr-rsrb-port", + 1997: "gdp-port", + 1998: "x25-svc-port", + 1999: "tcp-id-port", + 2000: "cisco-sccp", + 2001: "dc", + 2002: "globe", + 2003: "brutus", + 2004: "mailbox", + 2005: "berknet", + 2006: "invokator", + 2007: "dectalk", + 2008: "conf", + 2009: "news", + 2010: "search", + 2011: "raid-cc", + 2012: "ttyinfo", + 2013: "raid-am", + 2014: "troff", + 2015: "cypress", + 2016: "bootserver", + 2017: "cypress-stat", + 2018: "terminaldb", + 2019: "whosockami", + 2020: "xinupageserver", + 2021: "servexec", + 2022: "down", + 2023: "xinuexpansion3", + 2024: "xinuexpansion4", + 2025: "ellpack", + 2026: "scrabble", + 2027: "shadowserver", + 2028: "submitserver", + 2029: "hsrpv6", + 2030: "device2", + 2031: "mobrien-chat", + 2032: "blackboard", + 2033: "glogger", + 2034: "scoremgr", + 2035: "imsldoc", + 2036: "e-dpnet", + 2037: "applus", + 2038: "objectmanager", + 2039: "prizma", + 2040: "lam", + 2041: "interbase", + 2042: "isis", + 2043: "isis-bcast", + 2044: "rimsl", + 2045: "cdfunc", + 2046: "sdfunc", + 2047: "dls", + 2048: "dls-monitor", + 2049: "shilp", + 2050: "av-emb-config", + 2051: "epnsdp", + 2052: "clearvisn", + 2053: "lot105-ds-upd", + 2054: "weblogin", + 2055: "iop", + 2056: "omnisky", + 2057: "rich-cp", + 2058: "newwavesearch", + 2059: "bmc-messaging", + 2060: "teleniumdaemon", + 2061: "netmount", + 2062: "icg-swp", + 2063: "icg-bridge", + 2064: "icg-iprelay", + 2065: "dlsrpn", + 2066: "aura", + 2067: "dlswpn", + 2068: "avauthsrvprtcl", + 2069: "event-port", + 2070: "ah-esp-encap", + 2071: "acp-port", + 2072: "msync", + 2073: "gxs-data-port", + 2074: "vrtl-vmf-sa", + 2075: "newlixengine", + 2076: "newlixconfig", + 2077: "tsrmagt", + 2078: "tpcsrvr", + 2079: "idware-router", + 2080: "autodesk-nlm", + 2081: "kme-trap-port", + 2082: "infowave", + 2083: "radsec", + 2084: "sunclustergeo", + 2085: "ada-cip", + 2086: "gnunet", + 2087: "eli", + 2088: "ip-blf", + 2089: "sep", + 2090: "lrp", + 2091: "prp", + 2092: "descent3", + 2093: "nbx-cc", + 2094: "nbx-au", + 2095: "nbx-ser", + 2096: "nbx-dir", + 2097: "jetformpreview", + 2098: "dialog-port", + 2099: "h2250-annex-g", + 2100: "amiganetfs", + 2101: "rtcm-sc104", + 2102: "zephyr-srv", + 2103: "zephyr-clt", + 2104: "zephyr-hm", + 2105: "minipay", + 2106: "mzap", + 2107: "bintec-admin", + 2108: "comcam", + 2109: "ergolight", + 2110: "umsp", + 2111: "dsatp", + 2112: "idonix-metanet", + 2113: "hsl-storm", + 2114: "newheights", + 2115: "kdm", + 2116: "ccowcmr", + 2117: "mentaclient", + 2118: "mentaserver", + 2119: "gsigatekeeper", + 2120: "qencp", + 2121: "scientia-ssdb", + 2122: "caupc-remote", + 2123: "gtp-control", + 2124: "elatelink", + 2125: "lockstep", + 2126: "pktcable-cops", + 2127: "index-pc-wb", + 2128: "net-steward", + 2129: "cs-live", + 2130: "xds", + 2131: "avantageb2b", + 2132: "solera-epmap", + 2133: "zymed-zpp", + 2134: "avenue", + 2135: "gris", + 2136: "appworxsrv", + 2137: "connect", + 2138: "unbind-cluster", + 2139: "ias-auth", + 2140: "ias-reg", + 2141: "ias-admind", + 2142: "tdmoip", + 2143: "lv-jc", + 2144: "lv-ffx", + 2145: "lv-pici", + 2146: "lv-not", + 2147: "lv-auth", + 2148: "veritas-ucl", + 2149: "acptsys", + 2150: "dynamic3d", + 2151: "docent", + 2152: "gtp-user", + 2153: "ctlptc", + 2154: "stdptc", + 2155: "brdptc", + 2156: "trp", + 2157: "xnds", + 2158: "touchnetplus", + 2159: "gdbremote", + 2160: "apc-2160", + 2161: "apc-2161", + 2162: "navisphere", + 2163: "navisphere-sec", + 2164: "ddns-v3", + 2165: "x-bone-api", + 2166: "iwserver", + 2167: "raw-serial", + 2168: "easy-soft-mux", + 2169: "brain", + 2170: "eyetv", + 2171: "msfw-storage", + 2172: "msfw-s-storage", + 2173: "msfw-replica", + 2174: "msfw-array", + 2175: "airsync", + 2176: "rapi", + 2177: "qwave", + 2178: "bitspeer", + 2179: "vmrdp", + 2180: "mc-gt-srv", + 2181: "eforward", + 2182: "cgn-stat", + 2183: "cgn-config", + 2184: "nvd", + 2185: "onbase-dds", + 2186: "gtaua", + 2187: "ssmc", + 2188: "radware-rpm", + 2189: "radware-rpm-s", + 2190: "tivoconnect", + 2191: "tvbus", + 2192: "asdis", + 2193: "drwcs", + 2197: "mnp-exchange", + 2198: "onehome-remote", + 2199: "onehome-help", + 2200: "ici", + 2201: "ats", + 2202: "imtc-map", + 2203: "b2-runtime", + 2204: "b2-license", + 2205: "jps", + 2206: "hpocbus", + 2207: "hpssd", + 2208: "hpiod", + 2209: "rimf-ps", + 2210: "noaaport", + 2211: "emwin", + 2212: "leecoposserver", + 2213: "kali", + 2214: "rpi", + 2215: "ipcore", + 2216: "vtu-comms", + 2217: "gotodevice", + 2218: "bounzza", + 2219: "netiq-ncap", + 2220: "netiq", + 2221: "ethernet-ip-s", + 2222: "EtherNet-IP-1", + 2223: "rockwell-csp2", + 2224: "efi-mg", + 2225: "rcip-itu", + 2226: "di-drm", + 2227: "di-msg", + 2228: "ehome-ms", + 2229: "datalens", + 2230: "queueadm", + 2231: "wimaxasncp", + 2232: "ivs-video", + 2233: "infocrypt", + 2234: "directplay", + 2235: "sercomm-wlink", + 2236: "nani", + 2237: "optech-port1-lm", + 2238: "aviva-sna", + 2239: "imagequery", + 2240: "recipe", + 2241: "ivsd", + 2242: "foliocorp", + 2243: "magicom", + 2244: "nmsserver", + 2245: "hao", + 2246: "pc-mta-addrmap", + 2247: "antidotemgrsvr", + 2248: "ums", + 2249: "rfmp", + 2250: "remote-collab", + 2251: "dif-port", + 2252: "njenet-ssl", + 2253: "dtv-chan-req", + 2254: "seispoc", + 2255: "vrtp", + 2256: "pcc-mfp", + 2257: "simple-tx-rx", + 2258: "rcts", + 2260: "apc-2260", + 2261: "comotionmaster", + 2262: "comotionback", + 2263: "ecwcfg", + 2264: "apx500api-1", + 2265: "apx500api-2", + 2266: "mfserver", + 2267: "ontobroker", + 2268: "amt", + 2269: "mikey", + 2270: "starschool", + 2271: "mmcals", + 2272: "mmcal", + 2273: "mysql-im", + 2274: "pcttunnell", + 2275: "ibridge-data", + 2276: "ibridge-mgmt", + 2277: "bluectrlproxy", + 2278: "s3db", + 2279: "xmquery", + 2280: "lnvpoller", + 2281: "lnvconsole", + 2282: "lnvalarm", + 2283: "lnvstatus", + 2284: "lnvmaps", + 2285: "lnvmailmon", + 2286: "nas-metering", + 2287: "dna", + 2288: "netml", + 2289: "dict-lookup", + 2290: "sonus-logging", + 2291: "eapsp", + 2292: "mib-streaming", + 2293: "npdbgmngr", + 2294: "konshus-lm", + 2295: "advant-lm", + 2296: "theta-lm", + 2297: "d2k-datamover1", + 2298: "d2k-datamover2", + 2299: "pc-telecommute", + 2300: "cvmmon", + 2301: "cpq-wbem", + 2302: "binderysupport", + 2303: "proxy-gateway", + 2304: "attachmate-uts", + 2305: "mt-scaleserver", + 2306: "tappi-boxnet", + 2307: "pehelp", + 2308: "sdhelp", + 2309: "sdserver", + 2310: "sdclient", + 2311: "messageservice", + 2312: "wanscaler", + 2313: "iapp", + 2314: "cr-websystems", + 2315: "precise-sft", + 2316: "sent-lm", + 2317: "attachmate-g32", + 2318: "cadencecontrol", + 2319: "infolibria", + 2320: "siebel-ns", + 2321: "rdlap", + 2322: "ofsd", + 2323: "3d-nfsd", + 2324: "cosmocall", + 2325: "ansysli", + 2326: "idcp", + 2327: "xingcsm", + 2328: "netrix-sftm", + 2329: "nvd", + 2330: "tscchat", + 2331: "agentview", + 2332: "rcc-host", + 2333: "snapp", + 2334: "ace-client", + 2335: "ace-proxy", + 2336: "appleugcontrol", + 2337: "ideesrv", + 2338: "norton-lambert", + 2339: "3com-webview", + 2340: "wrs-registry", + 2341: "xiostatus", + 2342: "manage-exec", + 2343: "nati-logos", + 2344: "fcmsys", + 2345: "dbm", + 2346: "redstorm-join", + 2347: "redstorm-find", + 2348: "redstorm-info", + 2349: "redstorm-diag", + 2350: "psbserver", + 2351: "psrserver", + 2352: "pslserver", + 2353: "pspserver", + 2354: "psprserver", + 2355: "psdbserver", + 2356: "gxtelmd", + 2357: "unihub-server", + 2358: "futrix", + 2359: "flukeserver", + 2360: "nexstorindltd", + 2361: "tl1", + 2362: "digiman", + 2363: "mediacntrlnfsd", + 2364: "oi-2000", + 2365: "dbref", + 2366: "qip-login", + 2367: "service-ctrl", + 2368: "opentable", + 2370: "l3-hbmon", + 2371: "hp-rda", + 2372: "lanmessenger", + 2373: "remographlm", + 2374: "hydra", + 2375: "docker", + 2376: "docker-s", + 2377: "swarm", + 2379: "etcd-client", + 2380: "etcd-server", + 2381: "compaq-https", + 2382: "ms-olap3", + 2383: "ms-olap4", + 2384: "sd-request", + 2385: "sd-data", + 2386: "virtualtape", + 2387: "vsamredirector", + 2388: "mynahautostart", + 2389: "ovsessionmgr", + 2390: "rsmtp", + 2391: "3com-net-mgmt", + 2392: "tacticalauth", + 2393: "ms-olap1", + 2394: "ms-olap2", + 2395: "lan900-remote", + 2396: "wusage", + 2397: "ncl", + 2398: "orbiter", + 2399: "fmpro-fdal", + 2400: "opequus-server", + 2401: "cvspserver", + 2402: "taskmaster2000", + 2403: "taskmaster2000", + 2404: "iec-104", + 2405: "trc-netpoll", + 2406: "jediserver", + 2407: "orion", + 2408: "railgun-webaccl", + 2409: "sns-protocol", + 2410: "vrts-registry", + 2411: "netwave-ap-mgmt", + 2412: "cdn", + 2413: "orion-rmi-reg", + 2414: "beeyond", + 2415: "codima-rtp", + 2416: "rmtserver", + 2417: "composit-server", + 2418: "cas", + 2419: "attachmate-s2s", + 2420: "dslremote-mgmt", + 2421: "g-talk", + 2422: "crmsbits", + 2423: "rnrp", + 2424: "kofax-svr", + 2425: "fjitsuappmgr", + 2426: "vcmp", + 2427: "mgcp-gateway", + 2428: "ott", + 2429: "ft-role", + 2430: "venus", + 2431: "venus-se", + 2432: "codasrv", + 2433: "codasrv-se", + 2434: "pxc-epmap", + 2435: "optilogic", + 2436: "topx", + 2437: "unicontrol", + 2438: "msp", + 2439: "sybasedbsynch", + 2440: "spearway", + 2441: "pvsw-inet", + 2442: "netangel", + 2443: "powerclientcsf", + 2444: "btpp2sectrans", + 2445: "dtn1", + 2446: "bues-service", + 2447: "ovwdb", + 2448: "hpppssvr", + 2449: "ratl", + 2450: "netadmin", + 2451: "netchat", + 2452: "snifferclient", + 2453: "madge-ltd", + 2454: "indx-dds", + 2455: "wago-io-system", + 2456: "altav-remmgt", + 2457: "rapido-ip", + 2458: "griffin", + 2459: "community", + 2460: "ms-theater", + 2461: "qadmifoper", + 2462: "qadmifevent", + 2463: "lsi-raid-mgmt", + 2464: "direcpc-si", + 2465: "lbm", + 2466: "lbf", + 2467: "high-criteria", + 2468: "qip-msgd", + 2469: "mti-tcs-comm", + 2470: "taskman-port", + 2471: "seaodbc", + 2472: "c3", + 2473: "aker-cdp", + 2474: "vitalanalysis", + 2475: "ace-server", + 2476: "ace-svr-prop", + 2477: "ssm-cvs", + 2478: "ssm-cssps", + 2479: "ssm-els", + 2480: "powerexchange", + 2481: "giop", + 2482: "giop-ssl", + 2483: "ttc", + 2484: "ttc-ssl", + 2485: "netobjects1", + 2486: "netobjects2", + 2487: "pns", + 2488: "moy-corp", + 2489: "tsilb", + 2490: "qip-qdhcp", + 2491: "conclave-cpp", + 2492: "groove", + 2493: "talarian-mqs", + 2494: "bmc-ar", + 2495: "fast-rem-serv", + 2496: "dirgis", + 2497: "quaddb", + 2498: "odn-castraq", + 2499: "unicontrol", + 2500: "rtsserv", + 2501: "rtsclient", + 2502: "kentrox-prot", + 2503: "nms-dpnss", + 2504: "wlbs", + 2505: "ppcontrol", + 2506: "jbroker", + 2507: "spock", + 2508: "jdatastore", + 2509: "fjmpss", + 2510: "fjappmgrbulk", + 2511: "metastorm", + 2512: "citrixima", + 2513: "citrixadmin", + 2514: "facsys-ntp", + 2515: "facsys-router", + 2516: "maincontrol", + 2517: "call-sig-trans", + 2518: "willy", + 2519: "globmsgsvc", + 2520: "pvsw", + 2521: "adaptecmgr", + 2522: "windb", + 2523: "qke-llc-v3", + 2524: "optiwave-lm", + 2525: "ms-v-worlds", + 2526: "ema-sent-lm", + 2527: "iqserver", + 2528: "ncr-ccl", + 2529: "utsftp", + 2530: "vrcommerce", + 2531: "ito-e-gui", + 2532: "ovtopmd", + 2533: "snifferserver", + 2534: "combox-web-acc", + 2535: "madcap", + 2536: "btpp2audctr1", + 2537: "upgrade", + 2538: "vnwk-prapi", + 2539: "vsiadmin", + 2540: "lonworks", + 2541: "lonworks2", + 2542: "udrawgraph", + 2543: "reftek", + 2544: "novell-zen", + 2545: "sis-emt", + 2546: "vytalvaultbrtp", + 2547: "vytalvaultvsmp", + 2548: "vytalvaultpipe", + 2549: "ipass", + 2550: "ads", + 2551: "isg-uda-server", + 2552: "call-logging", + 2553: "efidiningport", + 2554: "vcnet-link-v10", + 2555: "compaq-wcp", + 2556: "nicetec-nmsvc", + 2557: "nicetec-mgmt", + 2558: "pclemultimedia", + 2559: "lstp", + 2560: "labrat", + 2561: "mosaixcc", + 2562: "delibo", + 2563: "cti-redwood", + 2564: "hp-3000-telnet", + 2565: "coord-svr", + 2566: "pcs-pcw", + 2567: "clp", + 2568: "spamtrap", + 2569: "sonuscallsig", + 2570: "hs-port", + 2571: "cecsvc", + 2572: "ibp", + 2573: "trustestablish", + 2574: "blockade-bpsp", + 2575: "hl7", + 2576: "tclprodebugger", + 2577: "scipticslsrvr", + 2578: "rvs-isdn-dcp", + 2579: "mpfoncl", + 2580: "tributary", + 2581: "argis-te", + 2582: "argis-ds", + 2583: "mon", + 2584: "cyaserv", + 2585: "netx-server", + 2586: "netx-agent", + 2587: "masc", + 2588: "privilege", + 2589: "quartus-tcl", + 2590: "idotdist", + 2591: "maytagshuffle", + 2592: "netrek", + 2593: "mns-mail", + 2594: "dts", + 2595: "worldfusion1", + 2596: "worldfusion2", + 2597: "homesteadglory", + 2598: "citriximaclient", + 2599: "snapd", + 2600: "hpstgmgr", + 2601: "discp-client", + 2602: "discp-server", + 2603: "servicemeter", + 2604: "nsc-ccs", + 2605: "nsc-posa", + 2606: "netmon", + 2607: "connection", + 2608: "wag-service", + 2609: "system-monitor", + 2610: "versa-tek", + 2611: "lionhead", + 2612: "qpasa-agent", + 2613: "smntubootstrap", + 2614: "neveroffline", + 2615: "firepower", + 2616: "appswitch-emp", + 2617: "cmadmin", + 2618: "priority-e-com", + 2619: "bruce", + 2620: "lpsrecommender", + 2621: "miles-apart", + 2622: "metricadbc", + 2623: "lmdp", + 2624: "aria", + 2625: "blwnkl-port", + 2626: "gbjd816", + 2627: "moshebeeri", + 2628: "dict", + 2629: "sitaraserver", + 2630: "sitaramgmt", + 2631: "sitaradir", + 2632: "irdg-post", + 2633: "interintelli", + 2634: "pk-electronics", + 2635: "backburner", + 2636: "solve", + 2637: "imdocsvc", + 2638: "sybaseanywhere", + 2639: "aminet", + 2640: "ami-control", + 2641: "hdl-srv", + 2642: "tragic", + 2643: "gte-samp", + 2644: "travsoft-ipx-t", + 2645: "novell-ipx-cmd", + 2646: "and-lm", + 2647: "syncserver", + 2648: "upsnotifyprot", + 2649: "vpsipport", + 2650: "eristwoguns", + 2651: "ebinsite", + 2652: "interpathpanel", + 2653: "sonus", + 2654: "corel-vncadmin", + 2655: "unglue", + 2656: "kana", + 2657: "sns-dispatcher", + 2658: "sns-admin", + 2659: "sns-query", + 2660: "gcmonitor", + 2661: "olhost", + 2662: "bintec-capi", + 2663: "bintec-tapi", + 2664: "patrol-mq-gm", + 2665: "patrol-mq-nm", + 2666: "extensis", + 2667: "alarm-clock-s", + 2668: "alarm-clock-c", + 2669: "toad", + 2670: "tve-announce", + 2671: "newlixreg", + 2672: "nhserver", + 2673: "firstcall42", + 2674: "ewnn", + 2675: "ttc-etap", + 2676: "simslink", + 2677: "gadgetgate1way", + 2678: "gadgetgate2way", + 2679: "syncserverssl", + 2680: "pxc-sapxom", + 2681: "mpnjsomb", + 2683: "ncdloadbalance", + 2684: "mpnjsosv", + 2685: "mpnjsocl", + 2686: "mpnjsomg", + 2687: "pq-lic-mgmt", + 2688: "md-cg-http", + 2689: "fastlynx", + 2690: "hp-nnm-data", + 2691: "itinternet", + 2692: "admins-lms", + 2694: "pwrsevent", + 2695: "vspread", + 2696: "unifyadmin", + 2697: "oce-snmp-trap", + 2698: "mck-ivpip", + 2699: "csoft-plusclnt", + 2700: "tqdata", + 2701: "sms-rcinfo", + 2702: "sms-xfer", + 2703: "sms-chat", + 2704: "sms-remctrl", + 2705: "sds-admin", + 2706: "ncdmirroring", + 2707: "emcsymapiport", + 2708: "banyan-net", + 2709: "supermon", + 2710: "sso-service", + 2711: "sso-control", + 2712: "aocp", + 2713: "raventbs", + 2714: "raventdm", + 2715: "hpstgmgr2", + 2716: "inova-ip-disco", + 2717: "pn-requester", + 2718: "pn-requester2", + 2719: "scan-change", + 2720: "wkars", + 2721: "smart-diagnose", + 2722: "proactivesrvr", + 2723: "watchdog-nt", + 2724: "qotps", + 2725: "msolap-ptp2", + 2726: "tams", + 2727: "mgcp-callagent", + 2728: "sqdr", + 2729: "tcim-control", + 2730: "nec-raidplus", + 2731: "fyre-messanger", + 2732: "g5m", + 2733: "signet-ctf", + 2734: "ccs-software", + 2735: "netiq-mc", + 2736: "radwiz-nms-srv", + 2737: "srp-feedback", + 2738: "ndl-tcp-ois-gw", + 2739: "tn-timing", + 2740: "alarm", + 2741: "tsb", + 2742: "tsb2", + 2743: "murx", + 2744: "honyaku", + 2745: "urbisnet", + 2746: "cpudpencap", + 2747: "fjippol-swrly", + 2748: "fjippol-polsvr", + 2749: "fjippol-cnsl", + 2750: "fjippol-port1", + 2751: "fjippol-port2", + 2752: "rsisysaccess", + 2753: "de-spot", + 2754: "apollo-cc", + 2755: "expresspay", + 2756: "simplement-tie", + 2757: "cnrp", + 2758: "apollo-status", + 2759: "apollo-gms", + 2760: "sabams", + 2761: "dicom-iscl", + 2762: "dicom-tls", + 2763: "desktop-dna", + 2764: "data-insurance", + 2765: "qip-audup", + 2766: "compaq-scp", + 2767: "uadtc", + 2768: "uacs", + 2769: "exce", + 2770: "veronica", + 2771: "vergencecm", + 2772: "auris", + 2773: "rbakcup1", + 2774: "rbakcup2", + 2775: "smpp", + 2776: "ridgeway1", + 2777: "ridgeway2", + 2778: "gwen-sonya", + 2779: "lbc-sync", + 2780: "lbc-control", + 2781: "whosells", + 2782: "everydayrc", + 2783: "aises", + 2784: "www-dev", + 2785: "aic-np", + 2786: "aic-oncrpc", + 2787: "piccolo", + 2788: "fryeserv", + 2789: "media-agent", + 2790: "plgproxy", + 2791: "mtport-regist", + 2792: "f5-globalsite", + 2793: "initlsmsad", + 2795: "livestats", + 2796: "ac-tech", + 2797: "esp-encap", + 2798: "tmesis-upshot", + 2799: "icon-discover", + 2800: "acc-raid", + 2801: "igcp", + 2802: "veritas-tcp1", + 2803: "btprjctrl", + 2804: "dvr-esm", + 2805: "wta-wsp-s", + 2806: "cspuni", + 2807: "cspmulti", + 2808: "j-lan-p", + 2809: "corbaloc", + 2810: "netsteward", + 2811: "gsiftp", + 2812: "atmtcp", + 2813: "llm-pass", + 2814: "llm-csv", + 2815: "lbc-measure", + 2816: "lbc-watchdog", + 2817: "nmsigport", + 2818: "rmlnk", + 2819: "fc-faultnotify", + 2820: "univision", + 2821: "vrts-at-port", + 2822: "ka0wuc", + 2823: "cqg-netlan", + 2824: "cqg-netlan-1", + 2826: "slc-systemlog", + 2827: "slc-ctrlrloops", + 2828: "itm-lm", + 2829: "silkp1", + 2830: "silkp2", + 2831: "silkp3", + 2832: "silkp4", + 2833: "glishd", + 2834: "evtp", + 2835: "evtp-data", + 2836: "catalyst", + 2837: "repliweb", + 2838: "starbot", + 2839: "nmsigport", + 2840: "l3-exprt", + 2841: "l3-ranger", + 2842: "l3-hawk", + 2843: "pdnet", + 2844: "bpcp-poll", + 2845: "bpcp-trap", + 2846: "aimpp-hello", + 2847: "aimpp-port-req", + 2848: "amt-blc-port", + 2849: "fxp", + 2850: "metaconsole", + 2851: "webemshttp", + 2852: "bears-01", + 2853: "ispipes", + 2854: "infomover", + 2855: "msrp", + 2856: "cesdinv", + 2857: "simctlp", + 2858: "ecnp", + 2859: "activememory", + 2860: "dialpad-voice1", + 2861: "dialpad-voice2", + 2862: "ttg-protocol", + 2863: "sonardata", + 2864: "astromed-main", + 2865: "pit-vpn", + 2866: "iwlistener", + 2867: "esps-portal", + 2868: "npep-messaging", + 2869: "icslap", + 2870: "daishi", + 2871: "msi-selectplay", + 2872: "radix", + 2874: "dxmessagebase1", + 2875: "dxmessagebase2", + 2876: "sps-tunnel", + 2877: "bluelance", + 2878: "aap", + 2879: "ucentric-ds", + 2880: "synapse", + 2881: "ndsp", + 2882: "ndtp", + 2883: "ndnp", + 2884: "flashmsg", + 2885: "topflow", + 2886: "responselogic", + 2887: "aironetddp", + 2888: "spcsdlobby", + 2889: "rsom", + 2890: "cspclmulti", + 2891: "cinegrfx-elmd", + 2892: "snifferdata", + 2893: "vseconnector", + 2894: "abacus-remote", + 2895: "natuslink", + 2896: "ecovisiong6-1", + 2897: "citrix-rtmp", + 2898: "appliance-cfg", + 2899: "powergemplus", + 2900: "quicksuite", + 2901: "allstorcns", + 2902: "netaspi", + 2903: "suitcase", + 2904: "m2ua", + 2905: "m3ua", + 2906: "caller9", + 2907: "webmethods-b2b", + 2908: "mao", + 2909: "funk-dialout", + 2910: "tdaccess", + 2911: "blockade", + 2912: "epicon", + 2913: "boosterware", + 2914: "gamelobby", + 2915: "tksocket", + 2916: "elvin-server", + 2917: "elvin-client", + 2918: "kastenchasepad", + 2919: "roboer", + 2920: "roboeda", + 2921: "cesdcdman", + 2922: "cesdcdtrn", + 2923: "wta-wsp-wtp-s", + 2924: "precise-vip", + 2926: "mobile-file-dl", + 2927: "unimobilectrl", + 2928: "redstone-cpss", + 2929: "amx-webadmin", + 2930: "amx-weblinx", + 2931: "circle-x", + 2932: "incp", + 2933: "4-tieropmgw", + 2934: "4-tieropmcli", + 2935: "qtp", + 2936: "otpatch", + 2937: "pnaconsult-lm", + 2938: "sm-pas-1", + 2939: "sm-pas-2", + 2940: "sm-pas-3", + 2941: "sm-pas-4", + 2942: "sm-pas-5", + 2943: "ttnrepository", + 2944: "megaco-h248", + 2945: "h248-binary", + 2946: "fjsvmpor", + 2947: "gpsd", + 2948: "wap-push", + 2949: "wap-pushsecure", + 2950: "esip", + 2951: "ottp", + 2952: "mpfwsas", + 2953: "ovalarmsrv", + 2954: "ovalarmsrv-cmd", + 2955: "csnotify", + 2956: "ovrimosdbman", + 2957: "jmact5", + 2958: "jmact6", + 2959: "rmopagt", + 2960: "dfoxserver", + 2961: "boldsoft-lm", + 2962: "iph-policy-cli", + 2963: "iph-policy-adm", + 2964: "bullant-srap", + 2965: "bullant-rap", + 2966: "idp-infotrieve", + 2967: "ssc-agent", + 2968: "enpp", + 2969: "essp", + 2970: "index-net", + 2971: "netclip", + 2972: "pmsm-webrctl", + 2973: "svnetworks", + 2974: "signal", + 2975: "fjmpcm", + 2976: "cns-srv-port", + 2977: "ttc-etap-ns", + 2978: "ttc-etap-ds", + 2979: "h263-video", + 2980: "wimd", + 2981: "mylxamport", + 2982: "iwb-whiteboard", + 2983: "netplan", + 2984: "hpidsadmin", + 2985: "hpidsagent", + 2986: "stonefalls", + 2987: "identify", + 2988: "hippad", + 2989: "zarkov", + 2990: "boscap", + 2991: "wkstn-mon", + 2992: "avenyo", + 2993: "veritas-vis1", + 2994: "veritas-vis2", + 2995: "idrs", + 2996: "vsixml", + 2997: "rebol", + 2998: "realsecure", + 2999: "remoteware-un", + 3000: "hbci", + 3001: "origo-native", + 3002: "exlm-agent", + 3003: "cgms", + 3004: "csoftragent", + 3005: "geniuslm", + 3006: "ii-admin", + 3007: "lotusmtap", + 3008: "midnight-tech", + 3009: "pxc-ntfy", + 3010: "gw", + 3011: "trusted-web", + 3012: "twsdss", + 3013: "gilatskysurfer", + 3014: "broker-service", + 3015: "nati-dstp", + 3016: "notify-srvr", + 3017: "event-listener", + 3018: "srvc-registry", + 3019: "resource-mgr", + 3020: "cifs", + 3021: "agriserver", + 3022: "csregagent", + 3023: "magicnotes", + 3024: "nds-sso", + 3025: "arepa-raft", + 3026: "agri-gateway", + 3027: "LiebDevMgmt-C", + 3028: "LiebDevMgmt-DM", + 3029: "LiebDevMgmt-A", + 3030: "arepa-cas", + 3031: "eppc", + 3032: "redwood-chat", + 3033: "pdb", + 3034: "osmosis-aeea", + 3035: "fjsv-gssagt", + 3036: "hagel-dump", + 3037: "hp-san-mgmt", + 3038: "santak-ups", + 3039: "cogitate", + 3040: "tomato-springs", + 3041: "di-traceware", + 3042: "journee", + 3043: "brp", + 3044: "epp", + 3045: "responsenet", + 3046: "di-ase", + 3047: "hlserver", + 3048: "pctrader", + 3049: "nsws", + 3050: "gds-db", + 3051: "galaxy-server", + 3052: "apc-3052", + 3053: "dsom-server", + 3054: "amt-cnf-prot", + 3055: "policyserver", + 3056: "cdl-server", + 3057: "goahead-fldup", + 3058: "videobeans", + 3059: "qsoft", + 3060: "interserver", + 3061: "cautcpd", + 3062: "ncacn-ip-tcp", + 3063: "ncadg-ip-udp", + 3064: "rprt", + 3065: "slinterbase", + 3066: "netattachsdmp", + 3067: "fjhpjp", + 3068: "ls3bcast", + 3069: "ls3", + 3070: "mgxswitch", + 3071: "xplat-replicate", + 3072: "csd-monitor", + 3073: "vcrp", + 3074: "xbox", + 3075: "orbix-locator", + 3076: "orbix-config", + 3077: "orbix-loc-ssl", + 3078: "orbix-cfg-ssl", + 3079: "lv-frontpanel", + 3080: "stm-pproc", + 3081: "tl1-lv", + 3082: "tl1-raw", + 3083: "tl1-telnet", + 3084: "itm-mccs", + 3085: "pcihreq", + 3086: "jdl-dbkitchen", + 3087: "asoki-sma", + 3088: "xdtp", + 3089: "ptk-alink", + 3090: "stss", + 3091: "1ci-smcs", + 3093: "rapidmq-center", + 3094: "rapidmq-reg", + 3095: "panasas", + 3096: "ndl-aps", + 3098: "umm-port", + 3099: "chmd", + 3100: "opcon-xps", + 3101: "hp-pxpib", + 3102: "slslavemon", + 3103: "autocuesmi", + 3104: "autocuelog", + 3105: "cardbox", + 3106: "cardbox-http", + 3107: "business", + 3108: "geolocate", + 3109: "personnel", + 3110: "sim-control", + 3111: "wsynch", + 3112: "ksysguard", + 3113: "cs-auth-svr", + 3114: "ccmad", + 3115: "mctet-master", + 3116: "mctet-gateway", + 3117: "mctet-jserv", + 3118: "pkagent", + 3119: "d2000kernel", + 3120: "d2000webserver", + 3121: "pcmk-remote", + 3122: "vtr-emulator", + 3123: "edix", + 3124: "beacon-port", + 3125: "a13-an", + 3127: "ctx-bridge", + 3128: "ndl-aas", + 3129: "netport-id", + 3130: "icpv2", + 3131: "netbookmark", + 3132: "ms-rule-engine", + 3133: "prism-deploy", + 3134: "ecp", + 3135: "peerbook-port", + 3136: "grubd", + 3137: "rtnt-1", + 3138: "rtnt-2", + 3139: "incognitorv", + 3140: "ariliamulti", + 3141: "vmodem", + 3142: "rdc-wh-eos", + 3143: "seaview", + 3144: "tarantella", + 3145: "csi-lfap", + 3146: "bears-02", + 3147: "rfio", + 3148: "nm-game-admin", + 3149: "nm-game-server", + 3150: "nm-asses-admin", + 3151: "nm-assessor", + 3152: "feitianrockey", + 3153: "s8-client-port", + 3154: "ccmrmi", + 3155: "jpegmpeg", + 3156: "indura", + 3157: "e3consultants", + 3158: "stvp", + 3159: "navegaweb-port", + 3160: "tip-app-server", + 3161: "doc1lm", + 3162: "sflm", + 3163: "res-sap", + 3164: "imprs", + 3165: "newgenpay", + 3166: "sossecollector", + 3167: "nowcontact", + 3168: "poweronnud", + 3169: "serverview-as", + 3170: "serverview-asn", + 3171: "serverview-gf", + 3172: "serverview-rm", + 3173: "serverview-icc", + 3174: "armi-server", + 3175: "t1-e1-over-ip", + 3176: "ars-master", + 3177: "phonex-port", + 3178: "radclientport", + 3179: "h2gf-w-2m", + 3180: "mc-brk-srv", + 3181: "bmcpatrolagent", + 3182: "bmcpatrolrnvu", + 3183: "cops-tls", + 3184: "apogeex-port", + 3185: "smpppd", + 3186: "iiw-port", + 3187: "odi-port", + 3188: "brcm-comm-port", + 3189: "pcle-infex", + 3190: "csvr-proxy", + 3191: "csvr-sslproxy", + 3192: "firemonrcc", + 3193: "spandataport", + 3194: "magbind", + 3195: "ncu-1", + 3196: "ncu-2", + 3197: "embrace-dp-s", + 3198: "embrace-dp-c", + 3199: "dmod-workspace", + 3200: "tick-port", + 3201: "cpq-tasksmart", + 3202: "intraintra", + 3203: "netwatcher-mon", + 3204: "netwatcher-db", + 3205: "isns", + 3206: "ironmail", + 3207: "vx-auth-port", + 3208: "pfu-prcallback", + 3209: "netwkpathengine", + 3210: "flamenco-proxy", + 3211: "avsecuremgmt", + 3212: "surveyinst", + 3213: "neon24x7", + 3214: "jmq-daemon-1", + 3215: "jmq-daemon-2", + 3216: "ferrari-foam", + 3217: "unite", + 3218: "smartpackets", + 3219: "wms-messenger", + 3220: "xnm-ssl", + 3221: "xnm-clear-text", + 3222: "glbp", + 3223: "digivote", + 3224: "aes-discovery", + 3225: "fcip-port", + 3226: "isi-irp", + 3227: "dwnmshttp", + 3228: "dwmsgserver", + 3229: "global-cd-port", + 3230: "sftdst-port", + 3231: "vidigo", + 3232: "mdtp", + 3233: "whisker", + 3234: "alchemy", + 3235: "mdap-port", + 3236: "apparenet-ts", + 3237: "apparenet-tps", + 3238: "apparenet-as", + 3239: "apparenet-ui", + 3240: "triomotion", + 3241: "sysorb", + 3242: "sdp-id-port", + 3243: "timelot", + 3244: "onesaf", + 3245: "vieo-fe", + 3246: "dvt-system", + 3247: "dvt-data", + 3248: "procos-lm", + 3249: "ssp", + 3250: "hicp", + 3251: "sysscanner", + 3252: "dhe", + 3253: "pda-data", + 3254: "pda-sys", + 3255: "semaphore", + 3256: "cpqrpm-agent", + 3257: "cpqrpm-server", + 3258: "ivecon-port", + 3259: "epncdp2", + 3260: "iscsi-target", + 3261: "winshadow", + 3262: "necp", + 3263: "ecolor-imager", + 3264: "ccmail", + 3265: "altav-tunnel", + 3266: "ns-cfg-server", + 3267: "ibm-dial-out", + 3268: "msft-gc", + 3269: "msft-gc-ssl", + 3270: "verismart", + 3271: "csoft-prev", + 3272: "user-manager", + 3273: "sxmp", + 3274: "ordinox-server", + 3275: "samd", + 3276: "maxim-asics", + 3277: "awg-proxy", + 3278: "lkcmserver", + 3279: "admind", + 3280: "vs-server", + 3281: "sysopt", + 3282: "datusorb", + 3283: "Apple Remote Desktop (Net Assistant)", + 3284: "4talk", + 3285: "plato", + 3286: "e-net", + 3287: "directvdata", + 3288: "cops", + 3289: "enpc", + 3290: "caps-lm", + 3291: "sah-lm", + 3292: "cart-o-rama", + 3293: "fg-fps", + 3294: "fg-gip", + 3295: "dyniplookup", + 3296: "rib-slm", + 3297: "cytel-lm", + 3298: "deskview", + 3299: "pdrncs", + 3300: "ceph", + 3302: "mcs-fastmail", + 3303: "opsession-clnt", + 3304: "opsession-srvr", + 3305: "odette-ftp", + 3306: "mysql", + 3307: "opsession-prxy", + 3308: "tns-server", + 3309: "tns-adv", + 3310: "dyna-access", + 3311: "mcns-tel-ret", + 3312: "appman-server", + 3313: "uorb", + 3314: "uohost", + 3315: "cdid", + 3316: "aicc-cmi", + 3317: "vsaiport", + 3318: "ssrip", + 3319: "sdt-lmd", + 3320: "officelink2000", + 3321: "vnsstr", + 3326: "sftu", + 3327: "bbars", + 3328: "egptlm", + 3329: "hp-device-disc", + 3330: "mcs-calypsoicf", + 3331: "mcs-messaging", + 3332: "mcs-mailsvr", + 3333: "dec-notes", + 3334: "directv-web", + 3335: "directv-soft", + 3336: "directv-tick", + 3337: "directv-catlg", + 3338: "anet-b", + 3339: "anet-l", + 3340: "anet-m", + 3341: "anet-h", + 3342: "webtie", + 3343: "ms-cluster-net", + 3344: "bnt-manager", + 3345: "influence", + 3346: "trnsprntproxy", + 3347: "phoenix-rpc", + 3348: "pangolin-laser", + 3349: "chevinservices", + 3350: "findviatv", + 3351: "btrieve", + 3352: "ssql", + 3353: "fatpipe", + 3354: "suitjd", + 3355: "ordinox-dbase", + 3356: "upnotifyps", + 3357: "adtech-test", + 3358: "mpsysrmsvr", + 3359: "wg-netforce", + 3360: "kv-server", + 3361: "kv-agent", + 3362: "dj-ilm", + 3363: "nati-vi-server", + 3364: "creativeserver", + 3365: "contentserver", + 3366: "creativepartnr", + 3372: "tip2", + 3373: "lavenir-lm", + 3374: "cluster-disc", + 3375: "vsnm-agent", + 3376: "cdbroker", + 3377: "cogsys-lm", + 3378: "wsicopy", + 3379: "socorfs", + 3380: "sns-channels", + 3381: "geneous", + 3382: "fujitsu-neat", + 3383: "esp-lm", + 3384: "hp-clic", + 3385: "qnxnetman", + 3386: "gprs-data", + 3387: "backroomnet", + 3388: "cbserver", + 3389: "ms-wbt-server", + 3390: "dsc", + 3391: "savant", + 3392: "efi-lm", + 3393: "d2k-tapestry1", + 3394: "d2k-tapestry2", + 3395: "dyna-lm", + 3396: "printer-agent", + 3397: "cloanto-lm", + 3398: "mercantile", + 3399: "csms", + 3400: "csms2", + 3401: "filecast", + 3402: "fxaengine-net", + 3405: "nokia-ann-ch1", + 3406: "nokia-ann-ch2", + 3407: "ldap-admin", + 3408: "BESApi", + 3409: "networklens", + 3410: "networklenss", + 3411: "biolink-auth", + 3412: "xmlblaster", + 3413: "svnet", + 3414: "wip-port", + 3415: "bcinameservice", + 3416: "commandport", + 3417: "csvr", + 3418: "rnmap", + 3419: "softaudit", + 3420: "ifcp-port", + 3421: "bmap", + 3422: "rusb-sys-port", + 3423: "xtrm", + 3424: "xtrms", + 3425: "agps-port", + 3426: "arkivio", + 3427: "websphere-snmp", + 3428: "twcss", + 3429: "gcsp", + 3430: "ssdispatch", + 3431: "ndl-als", + 3432: "osdcp", + 3433: "opnet-smp", + 3434: "opencm", + 3435: "pacom", + 3436: "gc-config", + 3437: "autocueds", + 3438: "spiral-admin", + 3439: "hri-port", + 3440: "ans-console", + 3441: "connect-client", + 3442: "connect-server", + 3443: "ov-nnm-websrv", + 3444: "denali-server", + 3445: "monp", + 3446: "3comfaxrpc", + 3447: "directnet", + 3448: "dnc-port", + 3449: "hotu-chat", + 3450: "castorproxy", + 3451: "asam", + 3452: "sabp-signal", + 3453: "pscupd", + 3454: "mira", + 3455: "prsvp", + 3456: "vat", + 3457: "vat-control", + 3458: "d3winosfi", + 3459: "integral", + 3460: "edm-manager", + 3461: "edm-stager", + 3462: "edm-std-notify", + 3463: "edm-adm-notify", + 3464: "edm-mgr-sync", + 3465: "edm-mgr-cntrl", + 3466: "workflow", + 3467: "rcst", + 3468: "ttcmremotectrl", + 3469: "pluribus", + 3470: "jt400", + 3471: "jt400-ssl", + 3472: "jaugsremotec-1", + 3473: "jaugsremotec-2", + 3474: "ttntspauto", + 3475: "genisar-port", + 3476: "nppmp", + 3477: "ecomm", + 3478: "stun", + 3479: "twrpc", + 3480: "plethora", + 3481: "cleanerliverc", + 3482: "vulture", + 3483: "slim-devices", + 3484: "gbs-stp", + 3485: "celatalk", + 3486: "ifsf-hb-port", + 3487: "ltctcp", + 3488: "fs-rh-srv", + 3489: "dtp-dia", + 3490: "colubris", + 3491: "swr-port", + 3492: "tvdumtray-port", + 3493: "nut", + 3494: "ibm3494", + 3495: "seclayer-tcp", + 3496: "seclayer-tls", + 3497: "ipether232port", + 3498: "dashpas-port", + 3499: "sccip-media", + 3500: "rtmp-port", + 3501: "isoft-p2p", + 3502: "avinstalldisc", + 3503: "lsp-ping", + 3504: "ironstorm", + 3505: "ccmcomm", + 3506: "apc-3506", + 3507: "nesh-broker", + 3508: "interactionweb", + 3509: "vt-ssl", + 3510: "xss-port", + 3511: "webmail-2", + 3512: "aztec", + 3513: "arcpd", + 3514: "must-p2p", + 3515: "must-backplane", + 3516: "smartcard-port", + 3517: "802-11-iapp", + 3518: "artifact-msg", + 3519: "nvmsgd", + 3520: "galileolog", + 3521: "mc3ss", + 3522: "nssocketport", + 3523: "odeumservlink", + 3524: "ecmport", + 3525: "eisport", + 3526: "starquiz-port", + 3527: "beserver-msg-q", + 3528: "jboss-iiop", + 3529: "jboss-iiop-ssl", + 3530: "gf", + 3531: "joltid", + 3532: "raven-rmp", + 3533: "raven-rdp", + 3534: "urld-port", + 3535: "ms-la", + 3536: "snac", + 3537: "ni-visa-remote", + 3538: "ibm-diradm", + 3539: "ibm-diradm-ssl", + 3540: "pnrp-port", + 3541: "voispeed-port", + 3542: "hacl-monitor", + 3543: "qftest-lookup", + 3544: "teredo", + 3545: "camac", + 3547: "symantec-sim", + 3548: "interworld", + 3549: "tellumat-nms", + 3550: "ssmpp", + 3551: "apcupsd", + 3552: "taserver", + 3553: "rbr-discovery", + 3554: "questnotify", + 3555: "razor", + 3556: "sky-transport", + 3557: "personalos-001", + 3558: "mcp-port", + 3559: "cctv-port", + 3560: "iniserve-port", + 3561: "bmc-onekey", + 3562: "sdbproxy", + 3563: "watcomdebug", + 3564: "esimport", + 3565: "m2pa", + 3566: "quest-data-hub", + 3567: "dof-eps", + 3568: "dof-tunnel-sec", + 3569: "mbg-ctrl", + 3570: "mccwebsvr-port", + 3571: "megardsvr-port", + 3572: "megaregsvrport", + 3573: "tag-ups-1", + 3574: "dmaf-server", + 3575: "ccm-port", + 3576: "cmc-port", + 3577: "config-port", + 3578: "data-port", + 3579: "ttat3lb", + 3580: "nati-svrloc", + 3581: "kfxaclicensing", + 3582: "press", + 3583: "canex-watch", + 3584: "u-dbap", + 3585: "emprise-lls", + 3586: "emprise-lsc", + 3587: "p2pgroup", + 3588: "sentinel", + 3589: "isomair", + 3590: "wv-csp-sms", + 3591: "gtrack-server", + 3592: "gtrack-ne", + 3593: "bpmd", + 3594: "mediaspace", + 3595: "shareapp", + 3596: "iw-mmogame", + 3597: "a14", + 3598: "a15", + 3599: "quasar-server", + 3600: "trap-daemon", + 3601: "visinet-gui", + 3602: "infiniswitchcl", + 3603: "int-rcv-cntrl", + 3604: "bmc-jmx-port", + 3605: "comcam-io", + 3606: "splitlock", + 3607: "precise-i3", + 3608: "trendchip-dcp", + 3609: "cpdi-pidas-cm", + 3610: "echonet", + 3611: "six-degrees", + 3612: "hp-dataprotect", + 3613: "alaris-disc", + 3614: "sigma-port", + 3615: "start-network", + 3616: "cd3o-protocol", + 3617: "sharp-server", + 3618: "aairnet-1", + 3619: "aairnet-2", + 3620: "ep-pcp", + 3621: "ep-nsp", + 3622: "ff-lr-port", + 3623: "haipe-discover", + 3624: "dist-upgrade", + 3625: "volley", + 3626: "bvcdaemon-port", + 3627: "jamserverport", + 3628: "ept-machine", + 3629: "escvpnet", + 3630: "cs-remote-db", + 3631: "cs-services", + 3632: "distcc", + 3633: "wacp", + 3634: "hlibmgr", + 3635: "sdo", + 3636: "servistaitsm", + 3637: "scservp", + 3638: "ehp-backup", + 3639: "xap-ha", + 3640: "netplay-port1", + 3641: "netplay-port2", + 3642: "juxml-port", + 3643: "audiojuggler", + 3644: "ssowatch", + 3645: "cyc", + 3646: "xss-srv-port", + 3647: "splitlock-gw", + 3648: "fjcp", + 3649: "nmmp", + 3650: "prismiq-plugin", + 3651: "xrpc-registry", + 3652: "vxcrnbuport", + 3653: "tsp", + 3654: "vaprtm", + 3655: "abatemgr", + 3656: "abatjss", + 3657: "immedianet-bcn", + 3658: "ps-ams", + 3659: "apple-sasl", + 3660: "can-nds-ssl", + 3661: "can-ferret-ssl", + 3662: "pserver", + 3663: "dtp", + 3664: "ups-engine", + 3665: "ent-engine", + 3666: "eserver-pap", + 3667: "infoexch", + 3668: "dell-rm-port", + 3669: "casanswmgmt", + 3670: "smile", + 3671: "efcp", + 3672: "lispworks-orb", + 3673: "mediavault-gui", + 3674: "wininstall-ipc", + 3675: "calltrax", + 3676: "va-pacbase", + 3677: "roverlog", + 3678: "ipr-dglt", + 3679: "Escale (Newton Dock)", + 3680: "npds-tracker", + 3681: "bts-x73", + 3682: "cas-mapi", + 3683: "bmc-ea", + 3684: "faxstfx-port", + 3685: "dsx-agent", + 3686: "tnmpv2", + 3687: "simple-push", + 3688: "simple-push-s", + 3689: "daap", + 3690: "svn", + 3691: "magaya-network", + 3692: "intelsync", + 3693: "easl", + 3695: "bmc-data-coll", + 3696: "telnetcpcd", + 3697: "nw-license", + 3698: "sagectlpanel", + 3699: "kpn-icw", + 3700: "lrs-paging", + 3701: "netcelera", + 3702: "ws-discovery", + 3703: "adobeserver-3", + 3704: "adobeserver-4", + 3705: "adobeserver-5", + 3706: "rt-event", + 3707: "rt-event-s", + 3708: "sun-as-iiops", + 3709: "ca-idms", + 3710: "portgate-auth", + 3711: "edb-server2", + 3712: "sentinel-ent", + 3713: "tftps", + 3714: "delos-dms", + 3715: "anoto-rendezv", + 3716: "wv-csp-sms-cir", + 3717: "wv-csp-udp-cir", + 3718: "opus-services", + 3719: "itelserverport", + 3720: "ufastro-instr", + 3721: "xsync", + 3722: "xserveraid", + 3723: "sychrond", + 3724: "blizwow", + 3725: "na-er-tip", + 3726: "array-manager", + 3727: "e-mdu", + 3728: "e-woa", + 3729: "fksp-audit", + 3730: "client-ctrl", + 3731: "smap", + 3732: "m-wnn", + 3733: "multip-msg", + 3734: "synel-data", + 3735: "pwdis", + 3736: "rs-rmi", + 3737: "xpanel", + 3738: "versatalk", + 3739: "launchbird-lm", + 3740: "heartbeat", + 3741: "wysdma", + 3742: "cst-port", + 3743: "ipcs-command", + 3744: "sasg", + 3745: "gw-call-port", + 3746: "linktest", + 3747: "linktest-s", + 3748: "webdata", + 3749: "cimtrak", + 3750: "cbos-ip-port", + 3751: "gprs-cube", + 3752: "vipremoteagent", + 3753: "nattyserver", + 3754: "timestenbroker", + 3755: "sas-remote-hlp", + 3756: "canon-capt", + 3757: "grf-port", + 3758: "apw-registry", + 3759: "exapt-lmgr", + 3760: "adtempusclient", + 3761: "gsakmp", + 3762: "gbs-smp", + 3763: "xo-wave", + 3764: "mni-prot-rout", + 3765: "rtraceroute", + 3766: "sitewatch-s", + 3767: "listmgr-port", + 3768: "rblcheckd", + 3769: "haipe-otnk", + 3770: "cindycollab", + 3771: "paging-port", + 3772: "ctp", + 3773: "ctdhercules", + 3774: "zicom", + 3775: "ispmmgr", + 3776: "dvcprov-port", + 3777: "jibe-eb", + 3778: "c-h-it-port", + 3779: "cognima", + 3780: "nnp", + 3781: "abcvoice-port", + 3782: "iso-tp0s", + 3783: "bim-pem", + 3784: "bfd-control", + 3785: "bfd-echo", + 3786: "upstriggervsw", + 3787: "fintrx", + 3788: "isrp-port", + 3789: "remotedeploy", + 3790: "quickbooksrds", + 3791: "tvnetworkvideo", + 3792: "sitewatch", + 3793: "dcsoftware", + 3794: "jaus", + 3795: "myblast", + 3796: "spw-dialer", + 3797: "idps", + 3798: "minilock", + 3799: "radius-dynauth", + 3800: "pwgpsi", + 3801: "ibm-mgr", + 3802: "vhd", + 3803: "soniqsync", + 3804: "iqnet-port", + 3805: "tcpdataserver", + 3806: "wsmlb", + 3807: "spugna", + 3808: "sun-as-iiops-ca", + 3809: "apocd", + 3810: "wlanauth", + 3811: "amp", + 3812: "neto-wol-server", + 3813: "rap-ip", + 3814: "neto-dcs", + 3815: "lansurveyorxml", + 3816: "sunlps-http", + 3817: "tapeware", + 3818: "crinis-hb", + 3819: "epl-slp", + 3820: "scp", + 3821: "pmcp", + 3822: "acp-discovery", + 3823: "acp-conduit", + 3824: "acp-policy", + 3825: "ffserver", + 3826: "warmux", + 3827: "netmpi", + 3828: "neteh", + 3829: "neteh-ext", + 3830: "cernsysmgmtagt", + 3831: "dvapps", + 3832: "xxnetserver", + 3833: "aipn-auth", + 3834: "spectardata", + 3835: "spectardb", + 3836: "markem-dcp", + 3837: "mkm-discovery", + 3838: "sos", + 3839: "amx-rms", + 3840: "flirtmitmir", + 3841: "shiprush-db-svr", + 3842: "nhci", + 3843: "quest-agent", + 3844: "rnm", + 3845: "v-one-spp", + 3846: "an-pcp", + 3847: "msfw-control", + 3848: "item", + 3849: "spw-dnspreload", + 3850: "qtms-bootstrap", + 3851: "spectraport", + 3852: "sse-app-config", + 3853: "sscan", + 3854: "stryker-com", + 3855: "opentrac", + 3856: "informer", + 3857: "trap-port", + 3858: "trap-port-mom", + 3859: "nav-port", + 3860: "sasp", + 3861: "winshadow-hd", + 3862: "giga-pocket", + 3863: "asap-tcp", + 3864: "asap-tcp-tls", + 3865: "xpl", + 3866: "dzdaemon", + 3867: "dzoglserver", + 3868: "diameter", + 3869: "ovsam-mgmt", + 3870: "ovsam-d-agent", + 3871: "avocent-adsap", + 3872: "oem-agent", + 3873: "fagordnc", + 3874: "sixxsconfig", + 3875: "pnbscada", + 3876: "dl-agent", + 3877: "xmpcr-interface", + 3878: "fotogcad", + 3879: "appss-lm", + 3880: "igrs", + 3881: "idac", + 3882: "msdts1", + 3883: "vrpn", + 3884: "softrack-meter", + 3885: "topflow-ssl", + 3886: "nei-management", + 3887: "ciphire-data", + 3888: "ciphire-serv", + 3889: "dandv-tester", + 3890: "ndsconnect", + 3891: "rtc-pm-port", + 3892: "pcc-image-port", + 3893: "cgi-starapi", + 3894: "syam-agent", + 3895: "syam-smc", + 3896: "sdo-tls", + 3897: "sdo-ssh", + 3898: "senip", + 3899: "itv-control", + 3900: "udt-os", + 3901: "nimsh", + 3902: "nimaux", + 3903: "charsetmgr", + 3904: "omnilink-port", + 3905: "mupdate", + 3906: "topovista-data", + 3907: "imoguia-port", + 3908: "hppronetman", + 3909: "surfcontrolcpa", + 3910: "prnrequest", + 3911: "prnstatus", + 3912: "gbmt-stars", + 3913: "listcrt-port", + 3914: "listcrt-port-2", + 3915: "agcat", + 3916: "wysdmc", + 3917: "aftmux", + 3918: "pktcablemmcops", + 3919: "hyperip", + 3920: "exasoftport1", + 3921: "herodotus-net", + 3922: "sor-update", + 3923: "symb-sb-port", + 3924: "mpl-gprs-port", + 3925: "zmp", + 3926: "winport", + 3927: "natdataservice", + 3928: "netboot-pxe", + 3929: "smauth-port", + 3930: "syam-webserver", + 3931: "msr-plugin-port", + 3932: "dyn-site", + 3933: "plbserve-port", + 3934: "sunfm-port", + 3935: "sdp-portmapper", + 3936: "mailprox", + 3937: "dvbservdsc", + 3938: "dbcontrol-agent", + 3939: "aamp", + 3940: "xecp-node", + 3941: "homeportal-web", + 3942: "srdp", + 3943: "tig", + 3944: "sops", + 3945: "emcads", + 3946: "backupedge", + 3947: "ccp", + 3948: "apdap", + 3949: "drip", + 3950: "namemunge", + 3951: "pwgippfax", + 3952: "i3-sessionmgr", + 3953: "xmlink-connect", + 3954: "adrep", + 3955: "p2pcommunity", + 3956: "gvcp", + 3957: "mqe-broker", + 3958: "mqe-agent", + 3959: "treehopper", + 3960: "bess", + 3961: "proaxess", + 3962: "sbi-agent", + 3963: "thrp", + 3964: "sasggprs", + 3965: "ati-ip-to-ncpe", + 3966: "bflckmgr", + 3967: "ppsms", + 3968: "ianywhere-dbns", + 3969: "landmarks", + 3970: "lanrevagent", + 3971: "lanrevserver", + 3972: "iconp", + 3973: "progistics", + 3974: "citysearch", + 3975: "airshot", + 3976: "opswagent", + 3977: "opswmanager", + 3978: "secure-cfg-svr", + 3979: "smwan", + 3980: "acms", + 3981: "starfish", + 3982: "eis", + 3983: "eisp", + 3984: "mapper-nodemgr", + 3985: "mapper-mapethd", + 3986: "mapper-ws-ethd", + 3987: "centerline", + 3988: "dcs-config", + 3989: "bv-queryengine", + 3990: "bv-is", + 3991: "bv-smcsrv", + 3992: "bv-ds", + 3993: "bv-agent", + 3995: "iss-mgmt-ssl", + 3996: "abcsoftware", + 3997: "agentsease-db", + 3998: "dnx", + 3999: "nvcnet", + 4000: "terabase", + 4001: "newoak", + 4002: "pxc-spvr-ft", + 4003: "pxc-splr-ft", + 4004: "pxc-roid", + 4005: "pxc-pin", + 4006: "pxc-spvr", + 4007: "pxc-splr", + 4008: "netcheque", + 4009: "chimera-hwm", + 4010: "samsung-unidex", + 4011: "altserviceboot", + 4012: "pda-gate", + 4013: "acl-manager", + 4014: "taiclock", + 4015: "talarian-mcast1", + 4016: "talarian-mcast2", + 4017: "talarian-mcast3", + 4018: "talarian-mcast4", + 4019: "talarian-mcast5", + 4020: "trap", + 4021: "nexus-portal", + 4022: "dnox", + 4023: "esnm-zoning", + 4024: "tnp1-port", + 4025: "partimage", + 4026: "as-debug", + 4027: "bxp", + 4028: "dtserver-port", + 4029: "ip-qsig", + 4030: "jdmn-port", + 4031: "suucp", + 4032: "vrts-auth-port", + 4033: "sanavigator", + 4034: "ubxd", + 4035: "wap-push-http", + 4036: "wap-push-https", + 4037: "ravehd", + 4038: "fazzt-ptp", + 4039: "fazzt-admin", + 4040: "yo-main", + 4041: "houston", + 4042: "ldxp", + 4043: "nirp", + 4044: "ltp", + 4045: "npp", + 4046: "acp-proto", + 4047: "ctp-state", + 4049: "wafs", + 4050: "cisco-wafs", + 4051: "cppdp", + 4052: "interact", + 4053: "ccu-comm-1", + 4054: "ccu-comm-2", + 4055: "ccu-comm-3", + 4056: "lms", + 4057: "wfm", + 4058: "kingfisher", + 4059: "dlms-cosem", + 4060: "dsmeter-iatc", + 4061: "ice-location", + 4062: "ice-slocation", + 4063: "ice-router", + 4064: "ice-srouter", + 4065: "avanti-cdp", + 4066: "pmas", + 4067: "idp", + 4068: "ipfltbcst", + 4069: "minger", + 4070: "tripe", + 4071: "aibkup", + 4072: "zieto-sock", + 4073: "iRAPP", + 4074: "cequint-cityid", + 4075: "perimlan", + 4076: "seraph", + 4078: "cssp", + 4079: "santools", + 4080: "lorica-in", + 4081: "lorica-in-sec", + 4082: "lorica-out", + 4083: "lorica-out-sec", + 4085: "ezmessagesrv", + 4087: "applusservice", + 4088: "npsp", + 4089: "opencore", + 4090: "omasgport", + 4091: "ewinstaller", + 4092: "ewdgs", + 4093: "pvxpluscs", + 4094: "sysrqd", + 4095: "xtgui", + 4096: "bre", + 4097: "patrolview", + 4098: "drmsfsd", + 4099: "dpcp", + 4100: "igo-incognito", + 4101: "brlp-0", + 4102: "brlp-1", + 4103: "brlp-2", + 4104: "brlp-3", + 4105: "shofar", + 4106: "synchronite", + 4107: "j-ac", + 4108: "accel", + 4109: "izm", + 4110: "g2tag", + 4111: "xgrid", + 4112: "apple-vpns-rp", + 4113: "aipn-reg", + 4114: "jomamqmonitor", + 4115: "cds", + 4116: "smartcard-tls", + 4117: "hillrserv", + 4118: "netscript", + 4119: "assuria-slm", + 4121: "e-builder", + 4122: "fprams", + 4123: "z-wave", + 4124: "tigv2", + 4125: "opsview-envoy", + 4126: "ddrepl", + 4127: "unikeypro", + 4128: "nufw", + 4129: "nuauth", + 4130: "fronet", + 4131: "stars", + 4132: "nuts-dem", + 4133: "nuts-bootp", + 4134: "nifty-hmi", + 4135: "cl-db-attach", + 4136: "cl-db-request", + 4137: "cl-db-remote", + 4138: "nettest", + 4139: "thrtx", + 4140: "cedros-fds", + 4141: "oirtgsvc", + 4142: "oidocsvc", + 4143: "oidsr", + 4145: "vvr-control", + 4146: "tgcconnect", + 4147: "vrxpservman", + 4148: "hhb-handheld", + 4149: "agslb", + 4150: "PowerAlert-nsa", + 4151: "menandmice-noh", + 4152: "idig-mux", + 4153: "mbl-battd", + 4154: "atlinks", + 4155: "bzr", + 4156: "stat-results", + 4157: "stat-scanner", + 4158: "stat-cc", + 4159: "nss", + 4160: "jini-discovery", + 4161: "omscontact", + 4162: "omstopology", + 4163: "silverpeakpeer", + 4164: "silverpeakcomm", + 4165: "altcp", + 4166: "joost", + 4167: "ddgn", + 4168: "pslicser", + 4169: "iadt", + 4170: "d-cinema-csp", + 4171: "ml-svnet", + 4172: "pcoip", + 4174: "smcluster", + 4175: "bccp", + 4176: "tl-ipcproxy", + 4177: "wello", + 4178: "storman", + 4179: "MaxumSP", + 4180: "httpx", + 4181: "macbak", + 4182: "pcptcpservice", + 4183: "cyborgnet", + 4184: "universe-suite", + 4185: "wcpp", + 4186: "boxbackupstore", + 4187: "csc-proxy", + 4188: "vatata", + 4189: "pcep", + 4190: "sieve", + 4192: "azeti", + 4193: "pvxplusio", + 4197: "hctl", + 4199: "eims-admin", + 4300: "corelccam", + 4301: "d-data", + 4302: "d-data-control", + 4303: "srcp", + 4304: "owserver", + 4305: "batman", + 4306: "pinghgl", + 4307: "trueconf", + 4308: "compx-lockview", + 4309: "dserver", + 4310: "mirrtex", + 4311: "p6ssmc", + 4312: "pscl-mgt", + 4313: "perrla", + 4314: "choiceview-agt", + 4316: "choiceview-clt", + 4320: "fdt-rcatp", + 4321: "rwhois", + 4322: "trim-event", + 4323: "trim-ice", + 4325: "geognosisman", + 4326: "geognosis", + 4327: "jaxer-web", + 4328: "jaxer-manager", + 4329: "publiqare-sync", + 4330: "dey-sapi", + 4331: "ktickets-rest", + 4333: "ahsp", + 4334: "netconf-ch-ssh", + 4335: "netconf-ch-tls", + 4336: "restconf-ch-tls", + 4340: "gaia", + 4341: "lisp-data", + 4342: "lisp-cons", + 4343: "unicall", + 4344: "vinainstall", + 4345: "m4-network-as", + 4346: "elanlm", + 4347: "lansurveyor", + 4348: "itose", + 4349: "fsportmap", + 4350: "net-device", + 4351: "plcy-net-svcs", + 4352: "pjlink", + 4353: "f5-iquery", + 4354: "qsnet-trans", + 4355: "qsnet-workst", + 4356: "qsnet-assist", + 4357: "qsnet-cond", + 4358: "qsnet-nucl", + 4359: "omabcastltkm", + 4360: "matrix-vnet", + 4368: "wxbrief", + 4369: "epmd", + 4370: "elpro-tunnel", + 4371: "l2c-control", + 4372: "l2c-data", + 4373: "remctl", + 4374: "psi-ptt", + 4375: "tolteces", + 4376: "bip", + 4377: "cp-spxsvr", + 4378: "cp-spxdpy", + 4379: "ctdb", + 4389: "xandros-cms", + 4390: "wiegand", + 4391: "apwi-imserver", + 4392: "apwi-rxserver", + 4393: "apwi-rxspooler", + 4395: "omnivisionesx", + 4396: "fly", + 4400: "ds-srv", + 4401: "ds-srvr", + 4402: "ds-clnt", + 4403: "ds-user", + 4404: "ds-admin", + 4405: "ds-mail", + 4406: "ds-slp", + 4407: "nacagent", + 4408: "slscc", + 4409: "netcabinet-com", + 4410: "itwo-server", + 4411: "found", + 4413: "avi-nms", + 4414: "updog", + 4415: "brcd-vr-req", + 4416: "pjj-player", + 4417: "workflowdir", + 4419: "cbp", + 4420: "nvm-express", + 4421: "scaleft", + 4422: "tsepisp", + 4423: "thingkit", + 4425: "netrockey6", + 4426: "beacon-port-2", + 4427: "drizzle", + 4428: "omviserver", + 4429: "omviagent", + 4430: "rsqlserver", + 4431: "wspipe", + 4432: "l-acoustics", + 4433: "vop", + 4442: "saris", + 4443: "pharos", + 4444: "krb524", + 4445: "upnotifyp", + 4446: "n1-fwp", + 4447: "n1-rmgmt", + 4448: "asc-slmd", + 4449: "privatewire", + 4450: "camp", + 4451: "ctisystemmsg", + 4452: "ctiprogramload", + 4453: "nssalertmgr", + 4454: "nssagentmgr", + 4455: "prchat-user", + 4456: "prchat-server", + 4457: "prRegister", + 4458: "mcp", + 4484: "hpssmgmt", + 4485: "assyst-dr", + 4486: "icms", + 4487: "prex-tcp", + 4488: "awacs-ice", + 4500: "ipsec-nat-t", + 4535: "ehs", + 4536: "ehs-ssl", + 4537: "wssauthsvc", + 4538: "swx-gate", + 4545: "worldscores", + 4546: "sf-lm", + 4547: "lanner-lm", + 4548: "synchromesh", + 4549: "aegate", + 4550: "gds-adppiw-db", + 4551: "ieee-mih", + 4552: "menandmice-mon", + 4553: "icshostsvc", + 4554: "msfrs", + 4555: "rsip", + 4556: "dtn-bundle", + 4559: "hylafax", + 4563: "amahi-anywhere", + 4566: "kwtc", + 4567: "tram", + 4568: "bmc-reporting", + 4569: "iax", + 4570: "deploymentmap", + 4573: "cardifftec-back", + 4590: "rid", + 4591: "l3t-at-an", + 4593: "ipt-anri-anri", + 4594: "ias-session", + 4595: "ias-paging", + 4596: "ias-neighbor", + 4597: "a21-an-1xbs", + 4598: "a16-an-an", + 4599: "a17-an-an", + 4600: "piranha1", + 4601: "piranha2", + 4602: "mtsserver", + 4603: "menandmice-upg", + 4604: "irp", + 4605: "sixchat", + 4658: "playsta2-app", + 4659: "playsta2-lob", + 4660: "smaclmgr", + 4661: "kar2ouche", + 4662: "oms", + 4663: "noteit", + 4664: "ems", + 4665: "contclientms", + 4666: "eportcomm", + 4667: "mmacomm", + 4668: "mmaeds", + 4669: "eportcommdata", + 4670: "light", + 4671: "acter", + 4672: "rfa", + 4673: "cxws", + 4674: "appiq-mgmt", + 4675: "dhct-status", + 4676: "dhct-alerts", + 4677: "bcs", + 4678: "traversal", + 4679: "mgesupervision", + 4680: "mgemanagement", + 4681: "parliant", + 4682: "finisar", + 4683: "spike", + 4684: "rfid-rp1", + 4685: "autopac", + 4686: "msp-os", + 4687: "nst", + 4688: "mobile-p2p", + 4689: "altovacentral", + 4690: "prelude", + 4691: "mtn", + 4692: "conspiracy", + 4700: "netxms-agent", + 4701: "netxms-mgmt", + 4702: "netxms-sync", + 4703: "npqes-test", + 4704: "assuria-ins", + 4711: "trinity-dist", + 4725: "truckstar", + 4727: "fcis", + 4728: "capmux", + 4730: "gearman", + 4731: "remcap", + 4733: "resorcs", + 4737: "ipdr-sp", + 4738: "solera-lpn", + 4739: "ipfix", + 4740: "ipfixs", + 4741: "lumimgrd", + 4742: "sicct", + 4743: "openhpid", + 4744: "ifsp", + 4745: "fmp", + 4749: "profilemac", + 4750: "ssad", + 4751: "spocp", + 4752: "snap", + 4753: "simon", + 4756: "RDCenter", + 4774: "converge", + 4784: "bfd-multi-ctl", + 4786: "smart-install", + 4787: "sia-ctrl-plane", + 4788: "xmcp", + 4800: "iims", + 4801: "iwec", + 4802: "ilss", + 4803: "notateit", + 4827: "htcp", + 4837: "varadero-0", + 4838: "varadero-1", + 4839: "varadero-2", + 4840: "opcua-tcp", + 4841: "quosa", + 4842: "gw-asv", + 4843: "opcua-tls", + 4844: "gw-log", + 4845: "wcr-remlib", + 4846: "contamac-icm", + 4847: "wfc", + 4848: "appserv-http", + 4849: "appserv-https", + 4850: "sun-as-nodeagt", + 4851: "derby-repli", + 4867: "unify-debug", + 4868: "phrelay", + 4869: "phrelaydbg", + 4870: "cc-tracking", + 4871: "wired", + 4876: "tritium-can", + 4877: "lmcs", + 4879: "wsdl-event", + 4880: "hislip", + 4883: "wmlserver", + 4884: "hivestor", + 4885: "abbs", + 4894: "lyskom", + 4899: "radmin-port", + 4900: "hfcs", + 4901: "flr-agent", + 4902: "magiccontrol", + 4912: "lutap", + 4913: "lutcp", + 4914: "bones", + 4915: "frcs", + 4940: "eq-office-4940", + 4941: "eq-office-4941", + 4942: "eq-office-4942", + 4949: "munin", + 4950: "sybasesrvmon", + 4951: "pwgwims", + 4952: "sagxtsds", + 4953: "dbsyncarbiter", + 4969: "ccss-qmm", + 4970: "ccss-qsm", + 4971: "burp", + 4984: "webyast", + 4985: "gerhcs", + 4986: "mrip", + 4987: "smar-se-port1", + 4988: "smar-se-port2", + 4989: "parallel", + 4990: "busycal", + 4991: "vrt", + 4999: "hfcs-manager", + 5000: "commplex-main", + 5001: "commplex-link", + 5002: "rfe", + 5003: "fmpro-internal", + 5004: "avt-profile-1", + 5005: "avt-profile-2", + 5006: "wsm-server", + 5007: "wsm-server-ssl", + 5008: "synapsis-edge", + 5009: "winfs", + 5010: "telelpathstart", + 5011: "telelpathattack", + 5012: "nsp", + 5013: "fmpro-v6", + 5015: "fmwp", + 5020: "zenginkyo-1", + 5021: "zenginkyo-2", + 5022: "mice", + 5023: "htuilsrv", + 5024: "scpi-telnet", + 5025: "scpi-raw", + 5026: "strexec-d", + 5027: "strexec-s", + 5028: "qvr", + 5029: "infobright", + 5030: "surfpass", + 5032: "signacert-agent", + 5033: "jtnetd-server", + 5034: "jtnetd-status", + 5042: "asnaacceler8db", + 5043: "swxadmin", + 5044: "lxi-evntsvc", + 5045: "osp", + 5048: "texai", + 5049: "ivocalize", + 5050: "mmcc", + 5051: "ita-agent", + 5052: "ita-manager", + 5053: "rlm", + 5054: "rlm-admin", + 5055: "unot", + 5056: "intecom-ps1", + 5057: "intecom-ps2", + 5059: "sds", + 5060: "sip", + 5061: "sips", + 5062: "na-localise", + 5063: "csrpc", + 5064: "ca-1", + 5065: "ca-2", + 5066: "stanag-5066", + 5067: "authentx", + 5068: "bitforestsrv", + 5069: "i-net-2000-npr", + 5070: "vtsas", + 5071: "powerschool", + 5072: "ayiya", + 5073: "tag-pm", + 5074: "alesquery", + 5075: "pvaccess", + 5080: "onscreen", + 5081: "sdl-ets", + 5082: "qcp", + 5083: "qfp", + 5084: "llrp", + 5085: "encrypted-llrp", + 5086: "aprigo-cs", + 5087: "biotic", + 5093: "sentinel-lm", + 5094: "hart-ip", + 5099: "sentlm-srv2srv", + 5100: "socalia", + 5101: "talarian-tcp", + 5102: "oms-nonsecure", + 5103: "actifio-c2c", + 5106: "actifioudsagent", + 5107: "actifioreplic", + 5111: "taep-as-svc", + 5112: "pm-cmdsvr", + 5114: "ev-services", + 5115: "autobuild", + 5117: "gradecam", + 5120: "barracuda-bbs", + 5133: "nbt-pc", + 5134: "ppactivation", + 5135: "erp-scale", + 5137: "ctsd", + 5145: "rmonitor-secure", + 5146: "social-alarm", + 5150: "atmp", + 5151: "esri-sde", + 5152: "sde-discovery", + 5153: "toruxserver", + 5154: "bzflag", + 5155: "asctrl-agent", + 5156: "rugameonline", + 5157: "mediat", + 5161: "snmpssh", + 5162: "snmpssh-trap", + 5163: "sbackup", + 5164: "vpa", + 5165: "ife-icorp", + 5166: "winpcs", + 5167: "scte104", + 5168: "scte30", + 5172: "pcoip-mgmt", + 5190: "aol", + 5191: "aol-1", + 5192: "aol-2", + 5193: "aol-3", + 5194: "cpscomm", + 5195: "ampl-lic", + 5196: "ampl-tableproxy", + 5197: "tunstall-lwp", + 5200: "targus-getdata", + 5201: "targus-getdata1", + 5202: "targus-getdata2", + 5203: "targus-getdata3", + 5209: "nomad", + 5215: "noteza", + 5221: "3exmp", + 5222: "xmpp-client", + 5223: "hpvirtgrp", + 5224: "hpvirtctrl", + 5225: "hp-server", + 5226: "hp-status", + 5227: "perfd", + 5228: "hpvroom", + 5229: "jaxflow", + 5230: "jaxflow-data", + 5231: "crusecontrol", + 5232: "csedaemon", + 5233: "enfs", + 5234: "eenet", + 5235: "galaxy-network", + 5236: "padl2sim", + 5237: "mnet-discovery", + 5245: "downtools", + 5248: "caacws", + 5249: "caaclang2", + 5250: "soagateway", + 5251: "caevms", + 5252: "movaz-ssc", + 5253: "kpdp", + 5254: "logcabin", + 5264: "3com-njack-1", + 5265: "3com-njack-2", + 5269: "xmpp-server", + 5270: "cartographerxmp", + 5271: "cuelink", + 5272: "pk", + 5280: "xmpp-bosh", + 5281: "undo-lm", + 5282: "transmit-port", + 5298: "presence", + 5299: "nlg-data", + 5300: "hacl-hb", + 5301: "hacl-gs", + 5302: "hacl-cfg", + 5303: "hacl-probe", + 5304: "hacl-local", + 5305: "hacl-test", + 5306: "sun-mc-grp", + 5307: "sco-aip", + 5308: "cfengine", + 5309: "jprinter", + 5310: "outlaws", + 5312: "permabit-cs", + 5313: "rrdp", + 5314: "opalis-rbt-ipc", + 5315: "hacl-poll", + 5316: "hpbladems", + 5317: "hpdevms", + 5318: "pkix-cmc", + 5320: "bsfserver-zn", + 5321: "bsfsvr-zn-ssl", + 5343: "kfserver", + 5344: "xkotodrcp", + 5349: "stuns", + 5352: "dns-llq", + 5353: "mdns", + 5354: "mdnsresponder", + 5355: "llmnr", + 5356: "ms-smlbiz", + 5357: "wsdapi", + 5358: "wsdapi-s", + 5359: "ms-alerter", + 5360: "ms-sideshow", + 5361: "ms-s-sideshow", + 5362: "serverwsd2", + 5363: "net-projection", + 5397: "stresstester", + 5398: "elektron-admin", + 5399: "securitychase", + 5400: "excerpt", + 5401: "excerpts", + 5402: "mftp", + 5403: "hpoms-ci-lstn", + 5404: "hpoms-dps-lstn", + 5405: "netsupport", + 5406: "systemics-sox", + 5407: "foresyte-clear", + 5408: "foresyte-sec", + 5409: "salient-dtasrv", + 5410: "salient-usrmgr", + 5411: "actnet", + 5412: "continuus", + 5413: "wwiotalk", + 5414: "statusd", + 5415: "ns-server", + 5416: "sns-gateway", + 5417: "sns-agent", + 5418: "mcntp", + 5419: "dj-ice", + 5420: "cylink-c", + 5421: "netsupport2", + 5422: "salient-mux", + 5423: "virtualuser", + 5424: "beyond-remote", + 5425: "br-channel", + 5426: "devbasic", + 5427: "sco-peer-tta", + 5428: "telaconsole", + 5429: "base", + 5430: "radec-corp", + 5431: "park-agent", + 5432: "postgresql", + 5433: "pyrrho", + 5434: "sgi-arrayd", + 5435: "sceanics", + 5443: "spss", + 5445: "smbdirect", + 5450: "tiepie", + 5453: "surebox", + 5454: "apc-5454", + 5455: "apc-5455", + 5456: "apc-5456", + 5461: "silkmeter", + 5462: "ttl-publisher", + 5463: "ttlpriceproxy", + 5464: "quailnet", + 5465: "netops-broker", + 5470: "apsolab-col", + 5471: "apsolab-cols", + 5472: "apsolab-tag", + 5473: "apsolab-tags", + 5475: "apsolab-data", + 5500: "fcp-addr-srvr1", + 5501: "fcp-addr-srvr2", + 5502: "fcp-srvr-inst1", + 5503: "fcp-srvr-inst2", + 5504: "fcp-cics-gw1", + 5505: "checkoutdb", + 5506: "amc", + 5507: "psl-management", + 5550: "cbus", + 5553: "sgi-eventmond", + 5554: "sgi-esphttp", + 5555: "personal-agent", + 5556: "freeciv", + 5557: "farenet", + 5565: "hpe-dp-bura", + 5566: "westec-connect", + 5567: "dof-dps-mc-sec", + 5568: "sdt", + 5569: "rdmnet-ctrl", + 5573: "sdmmp", + 5574: "lsi-bobcat", + 5575: "ora-oap", + 5579: "fdtracks", + 5580: "tmosms0", + 5581: "tmosms1", + 5582: "fac-restore", + 5583: "tmo-icon-sync", + 5584: "bis-web", + 5585: "bis-sync", + 5586: "att-mt-sms", + 5597: "ininmessaging", + 5598: "mctfeed", + 5599: "esinstall", + 5600: "esmmanager", + 5601: "esmagent", + 5602: "a1-msc", + 5603: "a1-bs", + 5604: "a3-sdunode", + 5605: "a4-sdunode", + 5618: "efr", + 5627: "ninaf", + 5628: "htrust", + 5629: "symantec-sfdb", + 5630: "precise-comm", + 5631: "pcanywheredata", + 5632: "pcanywherestat", + 5633: "beorl", + 5634: "xprtld", + 5635: "sfmsso", + 5636: "sfm-db-server", + 5637: "cssc", + 5638: "flcrs", + 5639: "ics", + 5646: "vfmobile", + 5666: "nrpe", + 5670: "filemq", + 5671: "amqps", + 5672: "amqp", + 5673: "jms", + 5674: "hyperscsi-port", + 5675: "v5ua", + 5676: "raadmin", + 5677: "questdb2-lnchr", + 5678: "rrac", + 5679: "dccm", + 5680: "auriga-router", + 5681: "ncxcp", + 5688: "ggz", + 5689: "qmvideo", + 5693: "rbsystem", + 5696: "kmip", + 5700: "supportassist", + 5705: "storageos", + 5713: "proshareaudio", + 5714: "prosharevideo", + 5715: "prosharedata", + 5716: "prosharerequest", + 5717: "prosharenotify", + 5718: "dpm", + 5719: "dpm-agent", + 5720: "ms-licensing", + 5721: "dtpt", + 5722: "msdfsr", + 5723: "omhs", + 5724: "omsdk", + 5725: "ms-ilm", + 5726: "ms-ilm-sts", + 5727: "asgenf", + 5728: "io-dist-data", + 5729: "openmail", + 5730: "unieng", + 5741: "ida-discover1", + 5742: "ida-discover2", + 5743: "watchdoc-pod", + 5744: "watchdoc", + 5745: "fcopy-server", + 5746: "fcopys-server", + 5747: "tunatic", + 5748: "tunalyzer", + 5750: "rscd", + 5755: "openmailg", + 5757: "x500ms", + 5766: "openmailns", + 5767: "s-openmail", + 5768: "openmailpxy", + 5769: "spramsca", + 5770: "spramsd", + 5771: "netagent", + 5777: "dali-port", + 5780: "vts-rpc", + 5781: "3par-evts", + 5782: "3par-mgmt", + 5783: "3par-mgmt-ssl", + 5785: "3par-rcopy", + 5793: "xtreamx", + 5813: "icmpd", + 5814: "spt-automation", + 5841: "shiprush-d-ch", + 5842: "reversion", + 5859: "wherehoo", + 5863: "ppsuitemsg", + 5868: "diameters", + 5883: "jute", + 5900: "rfb", + 5910: "cm", + 5911: "cpdlc", + 5912: "fis", + 5913: "ads-c", + 5963: "indy", + 5968: "mppolicy-v5", + 5969: "mppolicy-mgr", + 5984: "couchdb", + 5985: "wsman", + 5986: "wsmans", + 5987: "wbem-rmi", + 5988: "wbem-http", + 5989: "wbem-https", + 5990: "wbem-exp-https", + 5991: "nuxsl", + 5992: "consul-insight", + 5993: "cim-rs", + 5999: "cvsup", + 6064: "ndl-ahp-svc", + 6065: "winpharaoh", + 6066: "ewctsp", + 6068: "gsmp-ancp", + 6069: "trip", + 6070: "messageasap", + 6071: "ssdtp", + 6072: "diagnose-proc", + 6073: "directplay8", + 6074: "max", + 6075: "dpm-acm", + 6076: "msft-dpm-cert", + 6077: "iconstructsrv", + 6084: "reload-config", + 6085: "konspire2b", + 6086: "pdtp", + 6087: "ldss", + 6088: "doglms", + 6099: "raxa-mgmt", + 6100: "synchronet-db", + 6101: "synchronet-rtc", + 6102: "synchronet-upd", + 6103: "rets", + 6104: "dbdb", + 6105: "primaserver", + 6106: "mpsserver", + 6107: "etc-control", + 6108: "sercomm-scadmin", + 6109: "globecast-id", + 6110: "softcm", + 6111: "spc", + 6112: "dtspcd", + 6113: "dayliteserver", + 6114: "wrspice", + 6115: "xic", + 6116: "xtlserv", + 6117: "daylitetouch", + 6121: "spdy", + 6122: "bex-webadmin", + 6123: "backup-express", + 6124: "pnbs", + 6130: "damewaremobgtwy", + 6133: "nbt-wol", + 6140: "pulsonixnls", + 6141: "meta-corp", + 6142: "aspentec-lm", + 6143: "watershed-lm", + 6144: "statsci1-lm", + 6145: "statsci2-lm", + 6146: "lonewolf-lm", + 6147: "montage-lm", + 6148: "ricardo-lm", + 6149: "tal-pod", + 6159: "efb-aci", + 6160: "ecmp", + 6161: "patrol-ism", + 6162: "patrol-coll", + 6163: "pscribe", + 6200: "lm-x", + 6209: "qmtps", + 6222: "radmind", + 6241: "jeol-nsdtp-1", + 6242: "jeol-nsdtp-2", + 6243: "jeol-nsdtp-3", + 6244: "jeol-nsdtp-4", + 6251: "tl1-raw-ssl", + 6252: "tl1-ssh", + 6253: "crip", + 6267: "gld", + 6268: "grid", + 6269: "grid-alt", + 6300: "bmc-grx", + 6301: "bmc-ctd-ldap", + 6306: "ufmp", + 6315: "scup", + 6316: "abb-escp", + 6317: "nav-data-cmd", + 6320: "repsvc", + 6321: "emp-server1", + 6322: "emp-server2", + 6324: "hrd-ncs", + 6325: "dt-mgmtsvc", + 6326: "dt-vra", + 6343: "sflow", + 6344: "streletz", + 6346: "gnutella-svc", + 6347: "gnutella-rtr", + 6350: "adap", + 6355: "pmcs", + 6360: "metaedit-mu", + 6370: "metaedit-se", + 6379: "redis", + 6382: "metatude-mds", + 6389: "clariion-evr01", + 6390: "metaedit-ws", + 6417: "faxcomservice", + 6418: "syserverremote", + 6419: "svdrp", + 6420: "nim-vdrshell", + 6421: "nim-wan", + 6432: "pgbouncer", + 6442: "tarp", + 6443: "sun-sr-https", + 6444: "sge-qmaster", + 6445: "sge-execd", + 6446: "mysql-proxy", + 6455: "skip-cert-recv", + 6456: "skip-cert-send", + 6464: "ieee11073-20701", + 6471: "lvision-lm", + 6480: "sun-sr-http", + 6481: "servicetags", + 6482: "ldoms-mgmt", + 6483: "SunVTS-RMI", + 6484: "sun-sr-jms", + 6485: "sun-sr-iiop", + 6486: "sun-sr-iiops", + 6487: "sun-sr-iiop-aut", + 6488: "sun-sr-jmx", + 6489: "sun-sr-admin", + 6500: "boks", + 6501: "boks-servc", + 6502: "boks-servm", + 6503: "boks-clntd", + 6505: "badm-priv", + 6506: "badm-pub", + 6507: "bdir-priv", + 6508: "bdir-pub", + 6509: "mgcs-mfp-port", + 6510: "mcer-port", + 6513: "netconf-tls", + 6514: "syslog-tls", + 6515: "elipse-rec", + 6543: "lds-distrib", + 6544: "lds-dump", + 6547: "apc-6547", + 6548: "apc-6548", + 6549: "apc-6549", + 6550: "fg-sysupdate", + 6551: "sum", + 6558: "xdsxdm", + 6566: "sane-port", + 6568: "canit-store", + 6579: "affiliate", + 6580: "parsec-master", + 6581: "parsec-peer", + 6582: "parsec-game", + 6583: "joaJewelSuite", + 6600: "mshvlm", + 6601: "mstmg-sstp", + 6602: "wsscomfrmwk", + 6619: "odette-ftps", + 6620: "kftp-data", + 6621: "kftp", + 6622: "mcftp", + 6623: "ktelnet", + 6624: "datascaler-db", + 6625: "datascaler-ctl", + 6626: "wago-service", + 6627: "nexgen", + 6628: "afesc-mc", + 6629: "nexgen-aux", + 6632: "mxodbc-connect", + 6640: "ovsdb", + 6653: "openflow", + 6655: "pcs-sf-ui-man", + 6656: "emgmsg", + 6670: "vocaltec-gold", + 6671: "p4p-portal", + 6672: "vision-server", + 6673: "vision-elmd", + 6678: "vfbp", + 6679: "osaut", + 6687: "clever-ctrace", + 6688: "clever-tcpip", + 6689: "tsa", + 6690: "cleverdetect", + 6697: "ircs-u", + 6701: "kti-icad-srvr", + 6702: "e-design-net", + 6703: "e-design-web", + 6714: "ibprotocol", + 6715: "fibotrader-com", + 6716: "princity-agent", + 6767: "bmc-perf-agent", + 6768: "bmc-perf-mgrd", + 6769: "adi-gxp-srvprt", + 6770: "plysrv-http", + 6771: "plysrv-https", + 6777: "ntz-tracker", + 6778: "ntz-p2p-storage", + 6785: "dgpf-exchg", + 6786: "smc-jmx", + 6787: "smc-admin", + 6788: "smc-http", + 6789: "radg", + 6790: "hnmp", + 6791: "hnm", + 6801: "acnet", + 6817: "pentbox-sim", + 6831: "ambit-lm", + 6841: "netmo-default", + 6842: "netmo-http", + 6850: "iccrushmore", + 6868: "acctopus-cc", + 6888: "muse", + 6900: "rtimeviewer", + 6901: "jetstream", + 6935: "ethoscan", + 6936: "xsmsvc", + 6946: "bioserver", + 6951: "otlp", + 6961: "jmact3", + 6962: "jmevt2", + 6963: "swismgr1", + 6964: "swismgr2", + 6965: "swistrap", + 6966: "swispol", + 6969: "acmsoda", + 6970: "conductor", + 6997: "MobilitySrv", + 6998: "iatp-highpri", + 6999: "iatp-normalpri", + 7000: "afs3-fileserver", + 7001: "afs3-callback", + 7002: "afs3-prserver", + 7003: "afs3-vlserver", + 7004: "afs3-kaserver", + 7005: "afs3-volser", + 7006: "afs3-errors", + 7007: "afs3-bos", + 7008: "afs3-update", + 7009: "afs3-rmtsys", + 7010: "ups-onlinet", + 7011: "talon-disc", + 7012: "talon-engine", + 7013: "microtalon-dis", + 7014: "microtalon-com", + 7015: "talon-webserver", + 7016: "spg", + 7017: "grasp", + 7018: "fisa-svc", + 7019: "doceri-ctl", + 7020: "dpserve", + 7021: "dpserveadmin", + 7022: "ctdp", + 7023: "ct2nmcs", + 7024: "vmsvc", + 7025: "vmsvc-2", + 7030: "op-probe", + 7031: "iposplanet", + 7070: "arcp", + 7071: "iwg1", + 7073: "martalk", + 7080: "empowerid", + 7099: "lazy-ptop", + 7100: "font-service", + 7101: "elcn", + 7117: "rothaga", + 7121: "virprot-lm", + 7128: "scenidm", + 7129: "scenccs", + 7161: "cabsm-comm", + 7162: "caistoragemgr", + 7163: "cacsambroker", + 7164: "fsr", + 7165: "doc-server", + 7166: "aruba-server", + 7167: "casrmagent", + 7168: "cnckadserver", + 7169: "ccag-pib", + 7170: "nsrp", + 7171: "drm-production", + 7172: "metalbend", + 7173: "zsecure", + 7174: "clutild", + 7200: "fodms", + 7201: "dlip", + 7202: "pon-ictp", + 7215: "PS-Server", + 7216: "PS-Capture-Pro", + 7227: "ramp", + 7228: "citrixupp", + 7229: "citrixuppg", + 7236: "display", + 7237: "pads", + 7244: "frc-hicp", + 7262: "cnap", + 7272: "watchme-7272", + 7273: "oma-rlp", + 7274: "oma-rlp-s", + 7275: "oma-ulp", + 7276: "oma-ilp", + 7277: "oma-ilp-s", + 7278: "oma-dcdocbs", + 7279: "ctxlic", + 7280: "itactionserver1", + 7281: "itactionserver2", + 7282: "mzca-action", + 7283: "genstat", + 7365: "lcm-server", + 7391: "mindfilesys", + 7392: "mrssrendezvous", + 7393: "nfoldman", + 7394: "fse", + 7395: "winqedit", + 7397: "hexarc", + 7400: "rtps-discovery", + 7401: "rtps-dd-ut", + 7402: "rtps-dd-mt", + 7410: "ionixnetmon", + 7411: "daqstream", + 7421: "mtportmon", + 7426: "pmdmgr", + 7427: "oveadmgr", + 7428: "ovladmgr", + 7429: "opi-sock", + 7430: "xmpv7", + 7431: "pmd", + 7437: "faximum", + 7443: "oracleas-https", + 7471: "sttunnel", + 7473: "rise", + 7474: "neo4j", + 7478: "openit", + 7491: "telops-lmd", + 7500: "silhouette", + 7501: "ovbus", + 7508: "adcp", + 7509: "acplt", + 7510: "ovhpas", + 7511: "pafec-lm", + 7542: "saratoga", + 7543: "atul", + 7544: "nta-ds", + 7545: "nta-us", + 7546: "cfs", + 7547: "cwmp", + 7548: "tidp", + 7549: "nls-tl", + 7551: "controlone-con", + 7560: "sncp", + 7563: "cfw", + 7566: "vsi-omega", + 7569: "dell-eql-asm", + 7570: "aries-kfinder", + 7574: "coherence", + 7588: "sun-lm", + 7606: "mipi-debug", + 7624: "indi", + 7626: "simco", + 7627: "soap-http", + 7628: "zen-pawn", + 7629: "xdas", + 7630: "hawk", + 7631: "tesla-sys-msg", + 7633: "pmdfmgt", + 7648: "cuseeme", + 7672: "imqstomp", + 7673: "imqstomps", + 7674: "imqtunnels", + 7675: "imqtunnel", + 7676: "imqbrokerd", + 7677: "sun-user-https", + 7680: "pando-pub", + 7683: "dmt", + 7687: "bolt", + 7689: "collaber", + 7697: "klio", + 7700: "em7-secom", + 7707: "sync-em7", + 7708: "scinet", + 7720: "medimageportal", + 7724: "nsdeepfreezectl", + 7725: "nitrogen", + 7726: "freezexservice", + 7727: "trident-data", + 7728: "osvr", + 7734: "smip", + 7738: "aiagent", + 7741: "scriptview", + 7742: "msss", + 7743: "sstp-1", + 7744: "raqmon-pdu", + 7747: "prgp", + 7775: "inetfs", + 7777: "cbt", + 7778: "interwise", + 7779: "vstat", + 7781: "accu-lmgr", + 7786: "minivend", + 7787: "popup-reminders", + 7789: "office-tools", + 7794: "q3ade", + 7797: "pnet-conn", + 7798: "pnet-enc", + 7799: "altbsdp", + 7800: "asr", + 7801: "ssp-client", + 7810: "rbt-wanopt", + 7845: "apc-7845", + 7846: "apc-7846", + 7847: "csoauth", + 7869: "mobileanalyzer", + 7870: "rbt-smc", + 7871: "mdm", + 7878: "owms", + 7880: "pss", + 7887: "ubroker", + 7900: "mevent", + 7901: "tnos-sp", + 7902: "tnos-dp", + 7903: "tnos-dps", + 7913: "qo-secure", + 7932: "t2-drm", + 7933: "t2-brm", + 7962: "generalsync", + 7967: "supercell", + 7979: "micromuse-ncps", + 7980: "quest-vista", + 7981: "sossd-collect", + 7982: "sossd-agent", + 7997: "pushns", + 7999: "irdmi2", + 8000: "irdmi", + 8001: "vcom-tunnel", + 8002: "teradataordbms", + 8003: "mcreport", + 8005: "mxi", + 8006: "wpl-analytics", + 8007: "warppipe", + 8008: "http-alt", + 8019: "qbdb", + 8020: "intu-ec-svcdisc", + 8021: "intu-ec-client", + 8022: "oa-system", + 8025: "ca-audit-da", + 8026: "ca-audit-ds", + 8032: "pro-ed", + 8033: "mindprint", + 8034: "vantronix-mgmt", + 8040: "ampify", + 8041: "enguity-xccetp", + 8042: "fs-agent", + 8043: "fs-server", + 8044: "fs-mgmt", + 8051: "rocrail", + 8052: "senomix01", + 8053: "senomix02", + 8054: "senomix03", + 8055: "senomix04", + 8056: "senomix05", + 8057: "senomix06", + 8058: "senomix07", + 8059: "senomix08", + 8066: "toad-bi-appsrvr", + 8067: "infi-async", + 8070: "ucs-isc", + 8074: "gadugadu", + 8077: "mles", + 8080: "http-alt", + 8081: "sunproxyadmin", + 8082: "us-cli", + 8083: "us-srv", + 8086: "d-s-n", + 8087: "simplifymedia", + 8088: "radan-http", + 8090: "opsmessaging", + 8091: "jamlink", + 8097: "sac", + 8100: "xprint-server", + 8101: "ldoms-migr", + 8102: "kz-migr", + 8115: "mtl8000-matrix", + 8116: "cp-cluster", + 8117: "purityrpc", + 8118: "privoxy", + 8121: "apollo-data", + 8122: "apollo-admin", + 8128: "paycash-online", + 8129: "paycash-wbp", + 8130: "indigo-vrmi", + 8131: "indigo-vbcp", + 8132: "dbabble", + 8140: "puppet", + 8148: "isdd", + 8153: "quantastor", + 8160: "patrol", + 8161: "patrol-snmp", + 8162: "lpar2rrd", + 8181: "intermapper", + 8182: "vmware-fdm", + 8183: "proremote", + 8184: "itach", + 8190: "gcp-rphy", + 8191: "limnerpressure", + 8192: "spytechphone", + 8194: "blp1", + 8195: "blp2", + 8199: "vvr-data", + 8200: "trivnet1", + 8201: "trivnet2", + 8204: "lm-perfworks", + 8205: "lm-instmgr", + 8206: "lm-dta", + 8207: "lm-sserver", + 8208: "lm-webwatcher", + 8230: "rexecj", + 8243: "synapse-nhttps", + 8270: "robot-remote", + 8276: "pando-sec", + 8280: "synapse-nhttp", + 8282: "libelle", + 8292: "blp3", + 8293: "hiperscan-id", + 8294: "blp4", + 8300: "tmi", + 8301: "amberon", + 8313: "hub-open-net", + 8320: "tnp-discover", + 8321: "tnp", + 8322: "garmin-marine", + 8351: "server-find", + 8376: "cruise-enum", + 8377: "cruise-swroute", + 8378: "cruise-config", + 8379: "cruise-diags", + 8380: "cruise-update", + 8383: "m2mservices", + 8400: "cvd", + 8401: "sabarsd", + 8402: "abarsd", + 8403: "admind", + 8404: "svcloud", + 8405: "svbackup", + 8415: "dlpx-sp", + 8416: "espeech", + 8417: "espeech-rtp", + 8423: "aritts", + 8442: "cybro-a-bus", + 8443: "pcsync-https", + 8444: "pcsync-http", + 8445: "copy", + 8450: "npmp", + 8457: "nexentamv", + 8470: "cisco-avp", + 8471: "pim-port", + 8472: "otv", + 8473: "vp2p", + 8474: "noteshare", + 8500: "fmtp", + 8501: "cmtp-mgt", + 8502: "ftnmtp", + 8554: "rtsp-alt", + 8555: "d-fence", + 8567: "dof-tunnel", + 8600: "asterix", + 8610: "canon-mfnp", + 8611: "canon-bjnp1", + 8612: "canon-bjnp2", + 8613: "canon-bjnp3", + 8614: "canon-bjnp4", + 8615: "imink", + 8665: "monetra", + 8666: "monetra-admin", + 8675: "msi-cps-rm", + 8686: "sun-as-jmxrmi", + 8688: "openremote-ctrl", + 8699: "vnyx", + 8711: "nvc", + 8733: "ibus", + 8750: "dey-keyneg", + 8763: "mc-appserver", + 8764: "openqueue", + 8765: "ultraseek-http", + 8766: "amcs", + 8770: "dpap", + 8778: "uec", + 8786: "msgclnt", + 8787: "msgsrvr", + 8793: "acd-pm", + 8800: "sunwebadmin", + 8804: "truecm", + 8873: "dxspider", + 8880: "cddbp-alt", + 8881: "galaxy4d", + 8883: "secure-mqtt", + 8888: "ddi-tcp-1", + 8889: "ddi-tcp-2", + 8890: "ddi-tcp-3", + 8891: "ddi-tcp-4", + 8892: "ddi-tcp-5", + 8893: "ddi-tcp-6", + 8894: "ddi-tcp-7", + 8899: "ospf-lite", + 8900: "jmb-cds1", + 8901: "jmb-cds2", + 8910: "manyone-http", + 8911: "manyone-xml", + 8912: "wcbackup", + 8913: "dragonfly", + 8937: "twds", + 8953: "ub-dns-control", + 8954: "cumulus-admin", + 8980: "nod-provider", + 8989: "sunwebadmins", + 8990: "http-wmap", + 8991: "https-wmap", + 8997: "oracle-ms-ens", + 8998: "canto-roboflow", + 8999: "bctp", + 9000: "cslistener", + 9001: "etlservicemgr", + 9002: "dynamid", + 9005: "golem", + 9008: "ogs-server", + 9009: "pichat", + 9010: "sdr", + 9020: "tambora", + 9021: "panagolin-ident", + 9022: "paragent", + 9023: "swa-1", + 9024: "swa-2", + 9025: "swa-3", + 9026: "swa-4", + 9050: "versiera", + 9051: "fio-cmgmt", + 9060: "CardWeb-IO", + 9080: "glrpc", + 9083: "emc-pp-mgmtsvc", + 9084: "aurora", + 9085: "ibm-rsyscon", + 9086: "net2display", + 9087: "classic", + 9088: "sqlexec", + 9089: "sqlexec-ssl", + 9090: "websm", + 9091: "xmltec-xmlmail", + 9092: "XmlIpcRegSvc", + 9093: "copycat", + 9100: "hp-pdl-datastr", + 9101: "bacula-dir", + 9102: "bacula-fd", + 9103: "bacula-sd", + 9104: "peerwire", + 9105: "xadmin", + 9106: "astergate", + 9107: "astergatefax", + 9119: "mxit", + 9122: "grcmp", + 9123: "grcp", + 9131: "dddp", + 9160: "apani1", + 9161: "apani2", + 9162: "apani3", + 9163: "apani4", + 9164: "apani5", + 9191: "sun-as-jpda", + 9200: "wap-wsp", + 9201: "wap-wsp-wtp", + 9202: "wap-wsp-s", + 9203: "wap-wsp-wtp-s", + 9204: "wap-vcard", + 9205: "wap-vcal", + 9206: "wap-vcard-s", + 9207: "wap-vcal-s", + 9208: "rjcdb-vcards", + 9209: "almobile-system", + 9210: "oma-mlp", + 9211: "oma-mlp-s", + 9212: "serverviewdbms", + 9213: "serverstart", + 9214: "ipdcesgbs", + 9215: "insis", + 9216: "acme", + 9217: "fsc-port", + 9222: "teamcoherence", + 9255: "mon", + 9278: "pegasus", + 9279: "pegasus-ctl", + 9280: "pgps", + 9281: "swtp-port1", + 9282: "swtp-port2", + 9283: "callwaveiam", + 9284: "visd", + 9285: "n2h2server", + 9287: "cumulus", + 9292: "armtechdaemon", + 9293: "storview", + 9294: "armcenterhttp", + 9295: "armcenterhttps", + 9300: "vrace", + 9306: "sphinxql", + 9312: "sphinxapi", + 9318: "secure-ts", + 9321: "guibase", + 9343: "mpidcmgr", + 9344: "mphlpdmc", + 9345: "rancher", + 9346: "ctechlicensing", + 9374: "fjdmimgr", + 9380: "boxp", + 9387: "d2dconfig", + 9388: "d2ddatatrans", + 9389: "adws", + 9390: "otp", + 9396: "fjinvmgr", + 9397: "mpidcagt", + 9400: "sec-t4net-srv", + 9401: "sec-t4net-clt", + 9402: "sec-pc2fax-srv", + 9418: "git", + 9443: "tungsten-https", + 9444: "wso2esb-console", + 9445: "mindarray-ca", + 9450: "sntlkeyssrvr", + 9500: "ismserver", + 9535: "mngsuite", + 9536: "laes-bf", + 9555: "trispen-sra", + 9592: "ldgateway", + 9593: "cba8", + 9594: "msgsys", + 9595: "pds", + 9596: "mercury-disc", + 9597: "pd-admin", + 9598: "vscp", + 9599: "robix", + 9600: "micromuse-ncpw", + 9612: "streamcomm-ds", + 9614: "iadt-tls", + 9616: "erunbook-agent", + 9617: "erunbook-server", + 9618: "condor", + 9628: "odbcpathway", + 9629: "uniport", + 9630: "peoctlr", + 9631: "peocoll", + 9640: "pqsflows", + 9666: "zoomcp", + 9667: "xmms2", + 9668: "tec5-sdctp", + 9694: "client-wakeup", + 9695: "ccnx", + 9700: "board-roar", + 9747: "l5nas-parchan", + 9750: "board-voip", + 9753: "rasadv", + 9762: "tungsten-http", + 9800: "davsrc", + 9801: "sstp-2", + 9802: "davsrcs", + 9875: "sapv1", + 9876: "sd", + 9888: "cyborg-systems", + 9889: "gt-proxy", + 9898: "monkeycom", + 9900: "iua", + 9909: "domaintime", + 9911: "sype-transport", + 9925: "xybrid-cloud", + 9950: "apc-9950", + 9951: "apc-9951", + 9952: "apc-9952", + 9953: "acis", + 9954: "hinp", + 9955: "alljoyn-stm", + 9966: "odnsp", + 9978: "xybrid-rt", + 9979: "visweather", + 9981: "pumpkindb", + 9987: "dsm-scm-target", + 9988: "nsesrvr", + 9990: "osm-appsrvr", + 9991: "osm-oev", + 9992: "palace-1", + 9993: "palace-2", + 9994: "palace-3", + 9995: "palace-4", + 9996: "palace-5", + 9997: "palace-6", + 9998: "distinct32", + 9999: "distinct", + 10000: "ndmp", + 10001: "scp-config", + 10002: "documentum", + 10003: "documentum-s", + 10004: "emcrmirccd", + 10005: "emcrmird", + 10006: "netapp-sync", + 10007: "mvs-capacity", + 10008: "octopus", + 10009: "swdtp-sv", + 10010: "rxapi", + 10020: "abb-hw", + 10050: "zabbix-agent", + 10051: "zabbix-trapper", + 10055: "qptlmd", + 10080: "amanda", + 10081: "famdc", + 10100: "itap-ddtp", + 10101: "ezmeeting-2", + 10102: "ezproxy-2", + 10103: "ezrelay", + 10104: "swdtp", + 10107: "bctp-server", + 10110: "nmea-0183", + 10113: "netiq-endpoint", + 10114: "netiq-qcheck", + 10115: "netiq-endpt", + 10116: "netiq-voipa", + 10117: "iqrm", + 10125: "cimple", + 10128: "bmc-perf-sd", + 10129: "bmc-gms", + 10160: "qb-db-server", + 10161: "snmptls", + 10162: "snmptls-trap", + 10200: "trisoap", + 10201: "rsms", + 10252: "apollo-relay", + 10260: "axis-wimp-port", + 10261: "tile-ml", + 10288: "blocks", + 10321: "cosir", + 10540: "MOS-lower", + 10541: "MOS-upper", + 10542: "MOS-aux", + 10543: "MOS-soap", + 10544: "MOS-soap-opt", + 10548: "serverdocs", + 10631: "printopia", + 10800: "gap", + 10805: "lpdg", + 10809: "nbd", + 10860: "helix", + 10880: "bveapi", + 10933: "octopustentacle", + 10990: "rmiaux", + 11000: "irisa", + 11001: "metasys", + 11095: "weave", + 11103: "origo-sync", + 11104: "netapp-icmgmt", + 11105: "netapp-icdata", + 11106: "sgi-lk", + 11109: "sgi-dmfmgr", + 11110: "sgi-soap", + 11111: "vce", + 11112: "dicom", + 11161: "suncacao-snmp", + 11162: "suncacao-jmxmp", + 11163: "suncacao-rmi", + 11164: "suncacao-csa", + 11165: "suncacao-websvc", + 11172: "oemcacao-jmxmp", + 11173: "t5-straton", + 11174: "oemcacao-rmi", + 11175: "oemcacao-websvc", + 11201: "smsqp", + 11202: "dcsl-backup", + 11208: "wifree", + 11211: "memcache", + 11319: "imip", + 11320: "imip-channels", + 11321: "arena-server", + 11367: "atm-uhas", + 11371: "hkp", + 11489: "asgcypresstcps", + 11600: "tempest-port", + 11623: "emc-xsw-dconfig", + 11720: "h323callsigalt", + 11723: "emc-xsw-dcache", + 11751: "intrepid-ssl", + 11796: "lanschool", + 11876: "xoraya", + 11967: "sysinfo-sp", + 12000: "entextxid", + 12001: "entextnetwk", + 12002: "entexthigh", + 12003: "entextmed", + 12004: "entextlow", + 12005: "dbisamserver1", + 12006: "dbisamserver2", + 12007: "accuracer", + 12008: "accuracer-dbms", + 12010: "edbsrvr", + 12012: "vipera", + 12013: "vipera-ssl", + 12109: "rets-ssl", + 12121: "nupaper-ss", + 12168: "cawas", + 12172: "hivep", + 12300: "linogridengine", + 12302: "rads", + 12321: "warehouse-sss", + 12322: "warehouse", + 12345: "italk", + 12753: "tsaf", + 12865: "netperf", + 13160: "i-zipqd", + 13216: "bcslogc", + 13217: "rs-pias", + 13218: "emc-vcas-tcp", + 13223: "powwow-client", + 13224: "powwow-server", + 13400: "doip-data", + 13720: "bprd", + 13721: "bpdbm", + 13722: "bpjava-msvc", + 13724: "vnetd", + 13782: "bpcd", + 13783: "vopied", + 13785: "nbdb", + 13786: "nomdb", + 13818: "dsmcc-config", + 13819: "dsmcc-session", + 13820: "dsmcc-passthru", + 13821: "dsmcc-download", + 13822: "dsmcc-ccp", + 13823: "bmdss", + 13894: "ucontrol", + 13929: "dta-systems", + 13930: "medevolve", + 14000: "scotty-ft", + 14001: "sua", + 14033: "sage-best-com1", + 14034: "sage-best-com2", + 14141: "vcs-app", + 14142: "icpp", + 14143: "icpps", + 14145: "gcm-app", + 14149: "vrts-tdd", + 14150: "vcscmd", + 14154: "vad", + 14250: "cps", + 14414: "ca-web-update", + 14500: "xpra", + 14936: "hde-lcesrvr-1", + 14937: "hde-lcesrvr-2", + 15000: "hydap", + 15002: "onep-tls", + 15345: "xpilot", + 15363: "3link", + 15555: "cisco-snat", + 15660: "bex-xr", + 15740: "ptp", + 15999: "programmar", + 16000: "fmsas", + 16001: "fmsascon", + 16002: "gsms", + 16020: "jwpc", + 16021: "jwpc-bin", + 16161: "sun-sea-port", + 16162: "solaris-audit", + 16309: "etb4j", + 16310: "pduncs", + 16311: "pdefmns", + 16360: "netserialext1", + 16361: "netserialext2", + 16367: "netserialext3", + 16368: "netserialext4", + 16384: "connected", + 16385: "rdgs", + 16619: "xoms", + 16665: "axon-tunnel", + 16789: "cadsisvr", + 16900: "newbay-snc-mc", + 16950: "sgcip", + 16991: "intel-rci-mp", + 16992: "amt-soap-http", + 16993: "amt-soap-https", + 16994: "amt-redir-tcp", + 16995: "amt-redir-tls", + 17007: "isode-dua", + 17184: "vestasdlp", + 17185: "soundsvirtual", + 17219: "chipper", + 17220: "avtp", + 17221: "avdecc", + 17223: "isa100-gci", + 17225: "trdp-md", + 17234: "integrius-stp", + 17235: "ssh-mgmt", + 17500: "db-lsp", + 17555: "ailith", + 17729: "ea", + 17754: "zep", + 17755: "zigbee-ip", + 17756: "zigbee-ips", + 17777: "sw-orion", + 18000: "biimenu", + 18104: "radpdf", + 18136: "racf", + 18181: "opsec-cvp", + 18182: "opsec-ufp", + 18183: "opsec-sam", + 18184: "opsec-lea", + 18185: "opsec-omi", + 18186: "ohsc", + 18187: "opsec-ela", + 18241: "checkpoint-rtm", + 18242: "iclid", + 18243: "clusterxl", + 18262: "gv-pf", + 18463: "ac-cluster", + 18634: "rds-ib", + 18635: "rds-ip", + 18668: "vdmmesh", + 18769: "ique", + 18881: "infotos", + 18888: "apc-necmp", + 19000: "igrid", + 19007: "scintilla", + 19020: "j-link", + 19191: "opsec-uaa", + 19194: "ua-secureagent", + 19220: "cora", + 19283: "keysrvr", + 19315: "keyshadow", + 19398: "mtrgtrans", + 19410: "hp-sco", + 19411: "hp-sca", + 19412: "hp-sessmon", + 19539: "fxuptp", + 19540: "sxuptp", + 19541: "jcp", + 19998: "iec-104-sec", + 19999: "dnp-sec", + 20000: "dnp", + 20001: "microsan", + 20002: "commtact-http", + 20003: "commtact-https", + 20005: "openwebnet", + 20013: "ss-idi", + 20014: "opendeploy", + 20034: "nburn-id", + 20046: "tmophl7mts", + 20048: "mountd", + 20049: "nfsrdma", + 20057: "avesterra", + 20167: "tolfab", + 20202: "ipdtp-port", + 20222: "ipulse-ics", + 20480: "emwavemsg", + 20670: "track", + 20999: "athand-mmp", + 21000: "irtrans", + 21010: "notezilla-lan", + 21221: "aigairserver", + 21553: "rdm-tfs", + 21554: "dfserver", + 21590: "vofr-gateway", + 21800: "tvpm", + 21845: "webphone", + 21846: "netspeak-is", + 21847: "netspeak-cs", + 21848: "netspeak-acd", + 21849: "netspeak-cps", + 22000: "snapenetio", + 22001: "optocontrol", + 22002: "optohost002", + 22003: "optohost003", + 22004: "optohost004", + 22005: "optohost004", + 22125: "dcap", + 22128: "gsidcap", + 22222: "easyengine", + 22273: "wnn6", + 22305: "cis", + 22335: "shrewd-control", + 22343: "cis-secure", + 22347: "wibukey", + 22350: "codemeter", + 22351: "codemeter-cmwan", + 22537: "caldsoft-backup", + 22555: "vocaltec-wconf", + 22763: "talikaserver", + 22800: "aws-brf", + 22951: "brf-gw", + 23000: "inovaport1", + 23001: "inovaport2", + 23002: "inovaport3", + 23003: "inovaport4", + 23004: "inovaport5", + 23005: "inovaport6", + 23053: "gntp", + 23294: "5afe-dir", + 23333: "elxmgmt", + 23400: "novar-dbase", + 23401: "novar-alarm", + 23402: "novar-global", + 23456: "aequus", + 23457: "aequus-alt", + 23546: "areaguard-neo", + 24000: "med-ltp", + 24001: "med-fsp-rx", + 24002: "med-fsp-tx", + 24003: "med-supp", + 24004: "med-ovw", + 24005: "med-ci", + 24006: "med-net-svc", + 24242: "filesphere", + 24249: "vista-4gl", + 24321: "ild", + 24386: "intel-rci", + 24465: "tonidods", + 24554: "binkp", + 24577: "bilobit", + 24666: "sdtvwcam", + 24676: "canditv", + 24677: "flashfiler", + 24678: "proactivate", + 24680: "tcc-http", + 24754: "cslg", + 24922: "find", + 25000: "icl-twobase1", + 25001: "icl-twobase2", + 25002: "icl-twobase3", + 25003: "icl-twobase4", + 25004: "icl-twobase5", + 25005: "icl-twobase6", + 25006: "icl-twobase7", + 25007: "icl-twobase8", + 25008: "icl-twobase9", + 25009: "icl-twobase10", + 25576: "sauterdongle", + 25604: "idtp", + 25793: "vocaltec-hos", + 25900: "tasp-net", + 25901: "niobserver", + 25902: "nilinkanalyst", + 25903: "niprobe", + 26000: "quake", + 26133: "scscp", + 26208: "wnn6-ds", + 26257: "cockroach", + 26260: "ezproxy", + 26261: "ezmeeting", + 26262: "k3software-svr", + 26263: "k3software-cli", + 26486: "exoline-tcp", + 26487: "exoconfig", + 26489: "exonet", + 27345: "imagepump", + 27442: "jesmsjc", + 27504: "kopek-httphead", + 27782: "ars-vista", + 27876: "astrolink", + 27999: "tw-auth-key", + 28000: "nxlmd", + 28001: "pqsp", + 28200: "voxelstorm", + 28240: "siemensgsm", + 28589: "bosswave", + 29167: "otmp", + 29999: "bingbang", + 30000: "ndmps", + 30001: "pago-services1", + 30002: "pago-services2", + 30003: "amicon-fpsu-ra", + 30100: "rwp", + 30260: "kingdomsonline", + 30400: "gs-realtime", + 30999: "ovobs", + 31016: "ka-sddp", + 31020: "autotrac-acp", + 31400: "pace-licensed", + 31416: "xqosd", + 31457: "tetrinet", + 31620: "lm-mon", + 31685: "dsx-monitor", + 31765: "gamesmith-port", + 31948: "iceedcp-tx", + 31949: "iceedcp-rx", + 32034: "iracinghelper", + 32249: "t1distproc60", + 32400: "plex", + 32483: "apm-link", + 32635: "sec-ntb-clnt", + 32636: "DMExpress", + 32767: "filenet-powsrm", + 32768: "filenet-tms", + 32769: "filenet-rpc", + 32770: "filenet-nch", + 32771: "filenet-rmi", + 32772: "filenet-pa", + 32773: "filenet-cm", + 32774: "filenet-re", + 32775: "filenet-pch", + 32776: "filenet-peior", + 32777: "filenet-obrok", + 32801: "mlsn", + 32811: "retp", + 32896: "idmgratm", + 33060: "mysqlx", + 33123: "aurora-balaena", + 33331: "diamondport", + 33333: "dgi-serv", + 33334: "speedtrace", + 33434: "traceroute", + 33656: "snip-slave", + 34249: "turbonote-2", + 34378: "p-net-local", + 34379: "p-net-remote", + 34567: "dhanalakshmi", + 34962: "profinet-rt", + 34963: "profinet-rtm", + 34964: "profinet-cm", + 34980: "ethercat", + 35000: "heathview", + 35001: "rt-viewer", + 35002: "rt-sound", + 35003: "rt-devicemapper", + 35004: "rt-classmanager", + 35005: "rt-labtracker", + 35006: "rt-helper", + 35100: "axio-disc", + 35354: "kitim", + 35355: "altova-lm", + 35356: "guttersnex", + 35357: "openstack-id", + 36001: "allpeers", + 36524: "febooti-aw", + 36602: "observium-agent", + 36700: "mapx", + 36865: "kastenxpipe", + 37475: "neckar", + 37483: "gdrive-sync", + 37601: "eftp", + 37654: "unisys-eportal", + 38000: "ivs-database", + 38001: "ivs-insertion", + 38002: "cresco-control", + 38201: "galaxy7-data", + 38202: "fairview", + 38203: "agpolicy", + 38800: "sruth", + 38865: "secrmmsafecopya", + 39681: "turbonote-1", + 40000: "safetynetp", + 40404: "sptx", + 40841: "cscp", + 40842: "csccredir", + 40843: "csccfirewall", + 41111: "fs-qos", + 41121: "tentacle", + 41230: "z-wave-s", + 41794: "crestron-cip", + 41795: "crestron-ctp", + 41796: "crestron-cips", + 41797: "crestron-ctps", + 42508: "candp", + 42509: "candrp", + 42510: "caerpc", + 43000: "recvr-rc", + 43188: "reachout", + 43189: "ndm-agent-port", + 43190: "ip-provision", + 43191: "noit-transport", + 43210: "shaperai", + 43439: "eq3-update", + 43440: "ew-mgmt", + 43441: "ciscocsdb", + 44123: "z-wave-tunnel", + 44321: "pmcd", + 44322: "pmcdproxy", + 44323: "pmwebapi", + 44444: "cognex-dataman", + 44553: "rbr-debug", + 44818: "EtherNet-IP-2", + 44900: "m3da", + 45000: "asmp", + 45001: "asmps", + 45002: "rs-status", + 45045: "synctest", + 45054: "invision-ag", + 45514: "cloudcheck", + 45678: "eba", + 45824: "dai-shell", + 45825: "qdb2service", + 45966: "ssr-servermgr", + 46336: "inedo", + 46998: "spremotetablet", + 46999: "mediabox", + 47000: "mbus", + 47001: "winrm", + 47557: "dbbrowse", + 47624: "directplaysrvr", + 47806: "ap", + 47808: "bacnet", + 48000: "nimcontroller", + 48001: "nimspooler", + 48002: "nimhub", + 48003: "nimgtw", + 48004: "nimbusdb", + 48005: "nimbusdbctrl", + 48049: "3gpp-cbsp", + 48050: "weandsf", + 48128: "isnetserv", + 48129: "blp5", + 48556: "com-bardac-dw", + 48619: "iqobject", + 48653: "robotraconteur", + 49000: "matahari", + 49001: "nusrp", +} +var udpPortNames = map[UDPPort]string{ + 1: "tcpmux", + 2: "compressnet", + 3: "compressnet", + 5: "rje", + 7: "echo", + 9: "discard", + 11: "systat", + 13: "daytime", + 17: "qotd", + 18: "msp", + 19: "chargen", + 20: "ftp-data", + 21: "ftp", + 22: "ssh", + 23: "telnet", + 25: "smtp", + 27: "nsw-fe", + 29: "msg-icp", + 31: "msg-auth", + 33: "dsp", + 37: "time", + 38: "rap", + 39: "rlp", + 41: "graphics", + 42: "name", + 43: "nicname", + 44: "mpm-flags", + 45: "mpm", + 46: "mpm-snd", + 48: "auditd", + 49: "tacacs", + 50: "re-mail-ck", + 52: "xns-time", + 53: "domain", + 54: "xns-ch", + 55: "isi-gl", + 56: "xns-auth", + 58: "xns-mail", + 62: "acas", + 63: "whoispp", + 64: "covia", + 65: "tacacs-ds", + 66: "sql-net", + 67: "bootps", + 68: "bootpc", + 69: "tftp", + 70: "gopher", + 71: "netrjs-1", + 72: "netrjs-2", + 73: "netrjs-3", + 74: "netrjs-4", + 76: "deos", + 78: "vettcp", + 79: "finger", + 80: "http", + 82: "xfer", + 83: "mit-ml-dev", + 84: "ctf", + 85: "mit-ml-dev", + 86: "mfcobol", + 88: "kerberos", + 89: "su-mit-tg", + 90: "dnsix", + 91: "mit-dov", + 92: "npp", + 93: "dcp", + 94: "objcall", + 95: "supdup", + 96: "dixie", + 97: "swift-rvf", + 98: "tacnews", + 99: "metagram", + 101: "hostname", + 102: "iso-tsap", + 103: "gppitnp", + 104: "acr-nema", + 105: "cso", + 106: "3com-tsmux", + 107: "rtelnet", + 108: "snagas", + 109: "pop2", + 110: "pop3", + 111: "sunrpc", + 112: "mcidas", + 113: "auth", + 115: "sftp", + 116: "ansanotify", + 117: "uucp-path", + 118: "sqlserv", + 119: "nntp", + 120: "cfdptkt", + 121: "erpc", + 122: "smakynet", + 123: "ntp", + 124: "ansatrader", + 125: "locus-map", + 126: "nxedit", + 127: "locus-con", + 128: "gss-xlicen", + 129: "pwdgen", + 130: "cisco-fna", + 131: "cisco-tna", + 132: "cisco-sys", + 133: "statsrv", + 134: "ingres-net", + 135: "epmap", + 136: "profile", + 137: "netbios-ns", + 138: "netbios-dgm", + 139: "netbios-ssn", + 140: "emfis-data", + 141: "emfis-cntl", + 142: "bl-idm", + 143: "imap", + 144: "uma", + 145: "uaac", + 146: "iso-tp0", + 147: "iso-ip", + 148: "jargon", + 149: "aed-512", + 150: "sql-net", + 151: "hems", + 152: "bftp", + 153: "sgmp", + 154: "netsc-prod", + 155: "netsc-dev", + 156: "sqlsrv", + 157: "knet-cmp", + 158: "pcmail-srv", + 159: "nss-routing", + 160: "sgmp-traps", + 161: "snmp", + 162: "snmptrap", + 163: "cmip-man", + 164: "cmip-agent", + 165: "xns-courier", + 166: "s-net", + 167: "namp", + 168: "rsvd", + 169: "send", + 170: "print-srv", + 171: "multiplex", + 172: "cl-1", + 173: "xyplex-mux", + 174: "mailq", + 175: "vmnet", + 176: "genrad-mux", + 177: "xdmcp", + 178: "nextstep", + 179: "bgp", + 180: "ris", + 181: "unify", + 182: "audit", + 183: "ocbinder", + 184: "ocserver", + 185: "remote-kis", + 186: "kis", + 187: "aci", + 188: "mumps", + 189: "qft", + 190: "gacp", + 191: "prospero", + 192: "osu-nms", + 193: "srmp", + 194: "irc", + 195: "dn6-nlm-aud", + 196: "dn6-smm-red", + 197: "dls", + 198: "dls-mon", + 199: "smux", + 200: "src", + 201: "at-rtmp", + 202: "at-nbp", + 203: "at-3", + 204: "at-echo", + 205: "at-5", + 206: "at-zis", + 207: "at-7", + 208: "at-8", + 209: "qmtp", + 210: "z39-50", + 211: "914c-g", + 212: "anet", + 213: "ipx", + 214: "vmpwscs", + 215: "softpc", + 216: "CAIlic", + 217: "dbase", + 218: "mpp", + 219: "uarps", + 220: "imap3", + 221: "fln-spx", + 222: "rsh-spx", + 223: "cdc", + 224: "masqdialer", + 242: "direct", + 243: "sur-meas", + 244: "inbusiness", + 245: "link", + 246: "dsp3270", + 247: "subntbcst-tftp", + 248: "bhfhs", + 256: "rap", + 257: "set", + 259: "esro-gen", + 260: "openport", + 261: "nsiiops", + 262: "arcisdms", + 263: "hdap", + 264: "bgmp", + 265: "x-bone-ctl", + 266: "sst", + 267: "td-service", + 268: "td-replica", + 269: "manet", + 270: "gist", + 280: "http-mgmt", + 281: "personal-link", + 282: "cableport-ax", + 283: "rescap", + 284: "corerjd", + 286: "fxp", + 287: "k-block", + 308: "novastorbakcup", + 309: "entrusttime", + 310: "bhmds", + 311: "asip-webadmin", + 312: "vslmp", + 313: "magenta-logic", + 314: "opalis-robot", + 315: "dpsi", + 316: "decauth", + 317: "zannet", + 318: "pkix-timestamp", + 319: "ptp-event", + 320: "ptp-general", + 321: "pip", + 322: "rtsps", + 333: "texar", + 344: "pdap", + 345: "pawserv", + 346: "zserv", + 347: "fatserv", + 348: "csi-sgwp", + 349: "mftp", + 350: "matip-type-a", + 351: "matip-type-b", + 352: "dtag-ste-sb", + 353: "ndsauth", + 354: "bh611", + 355: "datex-asn", + 356: "cloanto-net-1", + 357: "bhevent", + 358: "shrinkwrap", + 359: "nsrmp", + 360: "scoi2odialog", + 361: "semantix", + 362: "srssend", + 363: "rsvp-tunnel", + 364: "aurora-cmgr", + 365: "dtk", + 366: "odmr", + 367: "mortgageware", + 368: "qbikgdp", + 369: "rpc2portmap", + 370: "codaauth2", + 371: "clearcase", + 372: "ulistproc", + 373: "legent-1", + 374: "legent-2", + 375: "hassle", + 376: "nip", + 377: "tnETOS", + 378: "dsETOS", + 379: "is99c", + 380: "is99s", + 381: "hp-collector", + 382: "hp-managed-node", + 383: "hp-alarm-mgr", + 384: "arns", + 385: "ibm-app", + 386: "asa", + 387: "aurp", + 388: "unidata-ldm", + 389: "ldap", + 390: "uis", + 391: "synotics-relay", + 392: "synotics-broker", + 393: "meta5", + 394: "embl-ndt", + 395: "netcp", + 396: "netware-ip", + 397: "mptn", + 398: "kryptolan", + 399: "iso-tsap-c2", + 400: "osb-sd", + 401: "ups", + 402: "genie", + 403: "decap", + 404: "nced", + 405: "ncld", + 406: "imsp", + 407: "timbuktu", + 408: "prm-sm", + 409: "prm-nm", + 410: "decladebug", + 411: "rmt", + 412: "synoptics-trap", + 413: "smsp", + 414: "infoseek", + 415: "bnet", + 416: "silverplatter", + 417: "onmux", + 418: "hyper-g", + 419: "ariel1", + 420: "smpte", + 421: "ariel2", + 422: "ariel3", + 423: "opc-job-start", + 424: "opc-job-track", + 425: "icad-el", + 426: "smartsdp", + 427: "svrloc", + 428: "ocs-cmu", + 429: "ocs-amu", + 430: "utmpsd", + 431: "utmpcd", + 432: "iasd", + 433: "nnsp", + 434: "mobileip-agent", + 435: "mobilip-mn", + 436: "dna-cml", + 437: "comscm", + 438: "dsfgw", + 439: "dasp", + 440: "sgcp", + 441: "decvms-sysmgt", + 442: "cvc-hostd", + 443: "https", + 444: "snpp", + 445: "microsoft-ds", + 446: "ddm-rdb", + 447: "ddm-dfm", + 448: "ddm-ssl", + 449: "as-servermap", + 450: "tserver", + 451: "sfs-smp-net", + 452: "sfs-config", + 453: "creativeserver", + 454: "contentserver", + 455: "creativepartnr", + 456: "macon-udp", + 457: "scohelp", + 458: "appleqtc", + 459: "ampr-rcmd", + 460: "skronk", + 461: "datasurfsrv", + 462: "datasurfsrvsec", + 463: "alpes", + 464: "kpasswd", + 465: "igmpv3lite", + 466: "digital-vrc", + 467: "mylex-mapd", + 468: "photuris", + 469: "rcp", + 470: "scx-proxy", + 471: "mondex", + 472: "ljk-login", + 473: "hybrid-pop", + 474: "tn-tl-w2", + 475: "tcpnethaspsrv", + 476: "tn-tl-fd1", + 477: "ss7ns", + 478: "spsc", + 479: "iafserver", + 480: "iafdbase", + 481: "ph", + 482: "bgs-nsi", + 483: "ulpnet", + 484: "integra-sme", + 485: "powerburst", + 486: "avian", + 487: "saft", + 488: "gss-http", + 489: "nest-protocol", + 490: "micom-pfs", + 491: "go-login", + 492: "ticf-1", + 493: "ticf-2", + 494: "pov-ray", + 495: "intecourier", + 496: "pim-rp-disc", + 497: "retrospect", + 498: "siam", + 499: "iso-ill", + 500: "isakmp", + 501: "stmf", + 502: "mbap", + 503: "intrinsa", + 504: "citadel", + 505: "mailbox-lm", + 506: "ohimsrv", + 507: "crs", + 508: "xvttp", + 509: "snare", + 510: "fcp", + 511: "passgo", + 512: "comsat", + 513: "who", + 514: "syslog", + 515: "printer", + 516: "videotex", + 517: "talk", + 518: "ntalk", + 519: "utime", + 520: "router", + 521: "ripng", + 522: "ulp", + 523: "ibm-db2", + 524: "ncp", + 525: "timed", + 526: "tempo", + 527: "stx", + 528: "custix", + 529: "irc-serv", + 530: "courier", + 531: "conference", + 532: "netnews", + 533: "netwall", + 534: "windream", + 535: "iiop", + 536: "opalis-rdv", + 537: "nmsp", + 538: "gdomap", + 539: "apertus-ldp", + 540: "uucp", + 541: "uucp-rlogin", + 542: "commerce", + 543: "klogin", + 544: "kshell", + 545: "appleqtcsrvr", + 546: "dhcpv6-client", + 547: "dhcpv6-server", + 548: "afpovertcp", + 549: "idfp", + 550: "new-rwho", + 551: "cybercash", + 552: "devshr-nts", + 553: "pirp", + 554: "rtsp", + 555: "dsf", + 556: "remotefs", + 557: "openvms-sysipc", + 558: "sdnskmp", + 559: "teedtap", + 560: "rmonitor", + 561: "monitor", + 562: "chshell", + 563: "nntps", + 564: "9pfs", + 565: "whoami", + 566: "streettalk", + 567: "banyan-rpc", + 568: "ms-shuttle", + 569: "ms-rome", + 570: "meter", + 571: "meter", + 572: "sonar", + 573: "banyan-vip", + 574: "ftp-agent", + 575: "vemmi", + 576: "ipcd", + 577: "vnas", + 578: "ipdd", + 579: "decbsrv", + 580: "sntp-heartbeat", + 581: "bdp", + 582: "scc-security", + 583: "philips-vc", + 584: "keyserver", + 586: "password-chg", + 587: "submission", + 588: "cal", + 589: "eyelink", + 590: "tns-cml", + 591: "http-alt", + 592: "eudora-set", + 593: "http-rpc-epmap", + 594: "tpip", + 595: "cab-protocol", + 596: "smsd", + 597: "ptcnameservice", + 598: "sco-websrvrmg3", + 599: "acp", + 600: "ipcserver", + 601: "syslog-conn", + 602: "xmlrpc-beep", + 603: "idxp", + 604: "tunnel", + 605: "soap-beep", + 606: "urm", + 607: "nqs", + 608: "sift-uft", + 609: "npmp-trap", + 610: "npmp-local", + 611: "npmp-gui", + 612: "hmmp-ind", + 613: "hmmp-op", + 614: "sshell", + 615: "sco-inetmgr", + 616: "sco-sysmgr", + 617: "sco-dtmgr", + 618: "dei-icda", + 619: "compaq-evm", + 620: "sco-websrvrmgr", + 621: "escp-ip", + 622: "collaborator", + 623: "asf-rmcp", + 624: "cryptoadmin", + 625: "dec-dlm", + 626: "asia", + 627: "passgo-tivoli", + 628: "qmqp", + 629: "3com-amp3", + 630: "rda", + 631: "ipp", + 632: "bmpp", + 633: "servstat", + 634: "ginad", + 635: "rlzdbase", + 636: "ldaps", + 637: "lanserver", + 638: "mcns-sec", + 639: "msdp", + 640: "entrust-sps", + 641: "repcmd", + 642: "esro-emsdp", + 643: "sanity", + 644: "dwr", + 645: "pssc", + 646: "ldp", + 647: "dhcp-failover", + 648: "rrp", + 649: "cadview-3d", + 650: "obex", + 651: "ieee-mms", + 652: "hello-port", + 653: "repscmd", + 654: "aodv", + 655: "tinc", + 656: "spmp", + 657: "rmc", + 658: "tenfold", + 660: "mac-srvr-admin", + 661: "hap", + 662: "pftp", + 663: "purenoise", + 664: "asf-secure-rmcp", + 665: "sun-dr", + 666: "mdqs", + 667: "disclose", + 668: "mecomm", + 669: "meregister", + 670: "vacdsm-sws", + 671: "vacdsm-app", + 672: "vpps-qua", + 673: "cimplex", + 674: "acap", + 675: "dctp", + 676: "vpps-via", + 677: "vpp", + 678: "ggf-ncp", + 679: "mrm", + 680: "entrust-aaas", + 681: "entrust-aams", + 682: "xfr", + 683: "corba-iiop", + 684: "corba-iiop-ssl", + 685: "mdc-portmapper", + 686: "hcp-wismar", + 687: "asipregistry", + 688: "realm-rusd", + 689: "nmap", + 690: "vatp", + 691: "msexch-routing", + 692: "hyperwave-isp", + 693: "connendp", + 694: "ha-cluster", + 695: "ieee-mms-ssl", + 696: "rushd", + 697: "uuidgen", + 698: "olsr", + 699: "accessnetwork", + 700: "epp", + 701: "lmp", + 702: "iris-beep", + 704: "elcsd", + 705: "agentx", + 706: "silc", + 707: "borland-dsj", + 709: "entrust-kmsh", + 710: "entrust-ash", + 711: "cisco-tdp", + 712: "tbrpf", + 713: "iris-xpc", + 714: "iris-xpcs", + 715: "iris-lwz", + 716: "pana", + 729: "netviewdm1", + 730: "netviewdm2", + 731: "netviewdm3", + 741: "netgw", + 742: "netrcs", + 744: "flexlm", + 747: "fujitsu-dev", + 748: "ris-cm", + 749: "kerberos-adm", + 750: "loadav", + 751: "pump", + 752: "qrh", + 753: "rrh", + 754: "tell", + 758: "nlogin", + 759: "con", + 760: "ns", + 761: "rxe", + 762: "quotad", + 763: "cycleserv", + 764: "omserv", + 765: "webster", + 767: "phonebook", + 769: "vid", + 770: "cadlock", + 771: "rtip", + 772: "cycleserv2", + 773: "notify", + 774: "acmaint-dbd", + 775: "acmaint-transd", + 776: "wpages", + 777: "multiling-http", + 780: "wpgs", + 800: "mdbs-daemon", + 801: "device", + 802: "mbap-s", + 810: "fcp-udp", + 828: "itm-mcell-s", + 829: "pkix-3-ca-ra", + 830: "netconf-ssh", + 831: "netconf-beep", + 832: "netconfsoaphttp", + 833: "netconfsoapbeep", + 847: "dhcp-failover2", + 848: "gdoi", + 853: "domain-s", + 854: "dlep", + 860: "iscsi", + 861: "owamp-control", + 862: "twamp-control", + 873: "rsync", + 886: "iclcnet-locate", + 887: "iclcnet-svinfo", + 888: "accessbuilder", + 900: "omginitialrefs", + 901: "smpnameres", + 902: "ideafarm-door", + 903: "ideafarm-panic", + 910: "kink", + 911: "xact-backup", + 912: "apex-mesh", + 913: "apex-edge", + 989: "ftps-data", + 990: "ftps", + 991: "nas", + 992: "telnets", + 993: "imaps", + 995: "pop3s", + 996: "vsinet", + 997: "maitrd", + 998: "puparp", + 999: "applix", + 1000: "cadlock2", + 1010: "surf", + 1021: "exp1", + 1022: "exp2", + 1025: "blackjack", + 1026: "cap", + 1027: "6a44", + 1029: "solid-mux", + 1033: "netinfo-local", + 1034: "activesync", + 1035: "mxxrlogin", + 1036: "nsstp", + 1037: "ams", + 1038: "mtqp", + 1039: "sbl", + 1040: "netarx", + 1041: "danf-ak2", + 1042: "afrog", + 1043: "boinc-client", + 1044: "dcutility", + 1045: "fpitp", + 1046: "wfremotertm", + 1047: "neod1", + 1048: "neod2", + 1049: "td-postman", + 1050: "cma", + 1051: "optima-vnet", + 1052: "ddt", + 1053: "remote-as", + 1054: "brvread", + 1055: "ansyslmd", + 1056: "vfo", + 1057: "startron", + 1058: "nim", + 1059: "nimreg", + 1060: "polestar", + 1061: "kiosk", + 1062: "veracity", + 1063: "kyoceranetdev", + 1064: "jstel", + 1065: "syscomlan", + 1066: "fpo-fns", + 1067: "instl-boots", + 1068: "instl-bootc", + 1069: "cognex-insight", + 1070: "gmrupdateserv", + 1071: "bsquare-voip", + 1072: "cardax", + 1073: "bridgecontrol", + 1074: "warmspotMgmt", + 1075: "rdrmshc", + 1076: "dab-sti-c", + 1077: "imgames", + 1078: "avocent-proxy", + 1079: "asprovatalk", + 1080: "socks", + 1081: "pvuniwien", + 1082: "amt-esd-prot", + 1083: "ansoft-lm-1", + 1084: "ansoft-lm-2", + 1085: "webobjects", + 1086: "cplscrambler-lg", + 1087: "cplscrambler-in", + 1088: "cplscrambler-al", + 1089: "ff-annunc", + 1090: "ff-fms", + 1091: "ff-sm", + 1092: "obrpd", + 1093: "proofd", + 1094: "rootd", + 1095: "nicelink", + 1096: "cnrprotocol", + 1097: "sunclustermgr", + 1098: "rmiactivation", + 1099: "rmiregistry", + 1100: "mctp", + 1101: "pt2-discover", + 1102: "adobeserver-1", + 1103: "adobeserver-2", + 1104: "xrl", + 1105: "ftranhc", + 1106: "isoipsigport-1", + 1107: "isoipsigport-2", + 1108: "ratio-adp", + 1110: "nfsd-keepalive", + 1111: "lmsocialserver", + 1112: "icp", + 1113: "ltp-deepspace", + 1114: "mini-sql", + 1115: "ardus-trns", + 1116: "ardus-cntl", + 1117: "ardus-mtrns", + 1118: "sacred", + 1119: "bnetgame", + 1120: "bnetfile", + 1121: "rmpp", + 1122: "availant-mgr", + 1123: "murray", + 1124: "hpvmmcontrol", + 1125: "hpvmmagent", + 1126: "hpvmmdata", + 1127: "kwdb-commn", + 1128: "saphostctrl", + 1129: "saphostctrls", + 1130: "casp", + 1131: "caspssl", + 1132: "kvm-via-ip", + 1133: "dfn", + 1134: "aplx", + 1135: "omnivision", + 1136: "hhb-gateway", + 1137: "trim", + 1138: "encrypted-admin", + 1139: "evm", + 1140: "autonoc", + 1141: "mxomss", + 1142: "edtools", + 1143: "imyx", + 1144: "fuscript", + 1145: "x9-icue", + 1146: "audit-transfer", + 1147: "capioverlan", + 1148: "elfiq-repl", + 1149: "bvtsonar", + 1150: "blaze", + 1151: "unizensus", + 1152: "winpoplanmess", + 1153: "c1222-acse", + 1154: "resacommunity", + 1155: "nfa", + 1156: "iascontrol-oms", + 1157: "iascontrol", + 1158: "dbcontrol-oms", + 1159: "oracle-oms", + 1160: "olsv", + 1161: "health-polling", + 1162: "health-trap", + 1163: "sddp", + 1164: "qsm-proxy", + 1165: "qsm-gui", + 1166: "qsm-remote", + 1167: "cisco-ipsla", + 1168: "vchat", + 1169: "tripwire", + 1170: "atc-lm", + 1171: "atc-appserver", + 1172: "dnap", + 1173: "d-cinema-rrp", + 1174: "fnet-remote-ui", + 1175: "dossier", + 1176: "indigo-server", + 1177: "dkmessenger", + 1178: "sgi-storman", + 1179: "b2n", + 1180: "mc-client", + 1181: "3comnetman", + 1182: "accelenet-data", + 1183: "llsurfup-http", + 1184: "llsurfup-https", + 1185: "catchpole", + 1186: "mysql-cluster", + 1187: "alias", + 1188: "hp-webadmin", + 1189: "unet", + 1190: "commlinx-avl", + 1191: "gpfs", + 1192: "caids-sensor", + 1193: "fiveacross", + 1194: "openvpn", + 1195: "rsf-1", + 1196: "netmagic", + 1197: "carrius-rshell", + 1198: "cajo-discovery", + 1199: "dmidi", + 1200: "scol", + 1201: "nucleus-sand", + 1202: "caiccipc", + 1203: "ssslic-mgr", + 1204: "ssslog-mgr", + 1205: "accord-mgc", + 1206: "anthony-data", + 1207: "metasage", + 1208: "seagull-ais", + 1209: "ipcd3", + 1210: "eoss", + 1211: "groove-dpp", + 1212: "lupa", + 1213: "mpc-lifenet", + 1214: "kazaa", + 1215: "scanstat-1", + 1216: "etebac5", + 1217: "hpss-ndapi", + 1218: "aeroflight-ads", + 1219: "aeroflight-ret", + 1220: "qt-serveradmin", + 1221: "sweetware-apps", + 1222: "nerv", + 1223: "tgp", + 1224: "vpnz", + 1225: "slinkysearch", + 1226: "stgxfws", + 1227: "dns2go", + 1228: "florence", + 1229: "zented", + 1230: "periscope", + 1231: "menandmice-lpm", + 1232: "first-defense", + 1233: "univ-appserver", + 1234: "search-agent", + 1235: "mosaicsyssvc1", + 1236: "bvcontrol", + 1237: "tsdos390", + 1238: "hacl-qs", + 1239: "nmsd", + 1240: "instantia", + 1241: "nessus", + 1242: "nmasoverip", + 1243: "serialgateway", + 1244: "isbconference1", + 1245: "isbconference2", + 1246: "payrouter", + 1247: "visionpyramid", + 1248: "hermes", + 1249: "mesavistaco", + 1250: "swldy-sias", + 1251: "servergraph", + 1252: "bspne-pcc", + 1253: "q55-pcc", + 1254: "de-noc", + 1255: "de-cache-query", + 1256: "de-server", + 1257: "shockwave2", + 1258: "opennl", + 1259: "opennl-voice", + 1260: "ibm-ssd", + 1261: "mpshrsv", + 1262: "qnts-orb", + 1263: "dka", + 1264: "prat", + 1265: "dssiapi", + 1266: "dellpwrappks", + 1267: "epc", + 1268: "propel-msgsys", + 1269: "watilapp", + 1270: "opsmgr", + 1271: "excw", + 1272: "cspmlockmgr", + 1273: "emc-gateway", + 1274: "t1distproc", + 1275: "ivcollector", + 1277: "miva-mqs", + 1278: "dellwebadmin-1", + 1279: "dellwebadmin-2", + 1280: "pictrography", + 1281: "healthd", + 1282: "emperion", + 1283: "productinfo", + 1284: "iee-qfx", + 1285: "neoiface", + 1286: "netuitive", + 1287: "routematch", + 1288: "navbuddy", + 1289: "jwalkserver", + 1290: "winjaserver", + 1291: "seagulllms", + 1292: "dsdn", + 1293: "pkt-krb-ipsec", + 1294: "cmmdriver", + 1295: "ehtp", + 1296: "dproxy", + 1297: "sdproxy", + 1298: "lpcp", + 1299: "hp-sci", + 1300: "h323hostcallsc", + 1301: "ci3-software-1", + 1302: "ci3-software-2", + 1303: "sftsrv", + 1304: "boomerang", + 1305: "pe-mike", + 1306: "re-conn-proto", + 1307: "pacmand", + 1308: "odsi", + 1309: "jtag-server", + 1310: "husky", + 1311: "rxmon", + 1312: "sti-envision", + 1313: "bmc-patroldb", + 1314: "pdps", + 1315: "els", + 1316: "exbit-escp", + 1317: "vrts-ipcserver", + 1318: "krb5gatekeeper", + 1319: "amx-icsp", + 1320: "amx-axbnet", + 1321: "pip", + 1322: "novation", + 1323: "brcd", + 1324: "delta-mcp", + 1325: "dx-instrument", + 1326: "wimsic", + 1327: "ultrex", + 1328: "ewall", + 1329: "netdb-export", + 1330: "streetperfect", + 1331: "intersan", + 1332: "pcia-rxp-b", + 1333: "passwrd-policy", + 1334: "writesrv", + 1335: "digital-notary", + 1336: "ischat", + 1337: "menandmice-dns", + 1338: "wmc-log-svc", + 1339: "kjtsiteserver", + 1340: "naap", + 1341: "qubes", + 1342: "esbroker", + 1343: "re101", + 1344: "icap", + 1345: "vpjp", + 1346: "alta-ana-lm", + 1347: "bbn-mmc", + 1348: "bbn-mmx", + 1349: "sbook", + 1350: "editbench", + 1351: "equationbuilder", + 1352: "lotusnote", + 1353: "relief", + 1354: "XSIP-network", + 1355: "intuitive-edge", + 1356: "cuillamartin", + 1357: "pegboard", + 1358: "connlcli", + 1359: "ftsrv", + 1360: "mimer", + 1361: "linx", + 1362: "timeflies", + 1363: "ndm-requester", + 1364: "ndm-server", + 1365: "adapt-sna", + 1366: "netware-csp", + 1367: "dcs", + 1368: "screencast", + 1369: "gv-us", + 1370: "us-gv", + 1371: "fc-cli", + 1372: "fc-ser", + 1373: "chromagrafx", + 1374: "molly", + 1375: "bytex", + 1376: "ibm-pps", + 1377: "cichlid", + 1378: "elan", + 1379: "dbreporter", + 1380: "telesis-licman", + 1381: "apple-licman", + 1382: "udt-os", + 1383: "gwha", + 1384: "os-licman", + 1385: "atex-elmd", + 1386: "checksum", + 1387: "cadsi-lm", + 1388: "objective-dbc", + 1389: "iclpv-dm", + 1390: "iclpv-sc", + 1391: "iclpv-sas", + 1392: "iclpv-pm", + 1393: "iclpv-nls", + 1394: "iclpv-nlc", + 1395: "iclpv-wsm", + 1396: "dvl-activemail", + 1397: "audio-activmail", + 1398: "video-activmail", + 1399: "cadkey-licman", + 1400: "cadkey-tablet", + 1401: "goldleaf-licman", + 1402: "prm-sm-np", + 1403: "prm-nm-np", + 1404: "igi-lm", + 1405: "ibm-res", + 1406: "netlabs-lm", + 1408: "sophia-lm", + 1409: "here-lm", + 1410: "hiq", + 1411: "af", + 1412: "innosys", + 1413: "innosys-acl", + 1414: "ibm-mqseries", + 1415: "dbstar", + 1416: "novell-lu6-2", + 1417: "timbuktu-srv1", + 1418: "timbuktu-srv2", + 1419: "timbuktu-srv3", + 1420: "timbuktu-srv4", + 1421: "gandalf-lm", + 1422: "autodesk-lm", + 1423: "essbase", + 1424: "hybrid", + 1425: "zion-lm", + 1426: "sais", + 1427: "mloadd", + 1428: "informatik-lm", + 1429: "nms", + 1430: "tpdu", + 1431: "rgtp", + 1432: "blueberry-lm", + 1433: "ms-sql-s", + 1434: "ms-sql-m", + 1435: "ibm-cics", + 1436: "saism", + 1437: "tabula", + 1438: "eicon-server", + 1439: "eicon-x25", + 1440: "eicon-slp", + 1441: "cadis-1", + 1442: "cadis-2", + 1443: "ies-lm", + 1444: "marcam-lm", + 1445: "proxima-lm", + 1446: "ora-lm", + 1447: "apri-lm", + 1448: "oc-lm", + 1449: "peport", + 1450: "dwf", + 1451: "infoman", + 1452: "gtegsc-lm", + 1453: "genie-lm", + 1454: "interhdl-elmd", + 1455: "esl-lm", + 1456: "dca", + 1457: "valisys-lm", + 1458: "nrcabq-lm", + 1459: "proshare1", + 1460: "proshare2", + 1461: "ibm-wrless-lan", + 1462: "world-lm", + 1463: "nucleus", + 1464: "msl-lmd", + 1465: "pipes", + 1466: "oceansoft-lm", + 1467: "csdmbase", + 1468: "csdm", + 1469: "aal-lm", + 1470: "uaiact", + 1471: "csdmbase", + 1472: "csdm", + 1473: "openmath", + 1474: "telefinder", + 1475: "taligent-lm", + 1476: "clvm-cfg", + 1477: "ms-sna-server", + 1478: "ms-sna-base", + 1479: "dberegister", + 1480: "pacerforum", + 1481: "airs", + 1482: "miteksys-lm", + 1483: "afs", + 1484: "confluent", + 1485: "lansource", + 1486: "nms-topo-serv", + 1487: "localinfosrvr", + 1488: "docstor", + 1489: "dmdocbroker", + 1490: "insitu-conf", + 1492: "stone-design-1", + 1493: "netmap-lm", + 1494: "ica", + 1495: "cvc", + 1496: "liberty-lm", + 1497: "rfx-lm", + 1498: "sybase-sqlany", + 1499: "fhc", + 1500: "vlsi-lm", + 1501: "saiscm", + 1502: "shivadiscovery", + 1503: "imtc-mcs", + 1504: "evb-elm", + 1505: "funkproxy", + 1506: "utcd", + 1507: "symplex", + 1508: "diagmond", + 1509: "robcad-lm", + 1510: "mvx-lm", + 1511: "3l-l1", + 1512: "wins", + 1513: "fujitsu-dtc", + 1514: "fujitsu-dtcns", + 1515: "ifor-protocol", + 1516: "vpad", + 1517: "vpac", + 1518: "vpvd", + 1519: "vpvc", + 1520: "atm-zip-office", + 1521: "ncube-lm", + 1522: "ricardo-lm", + 1523: "cichild-lm", + 1524: "ingreslock", + 1525: "orasrv", + 1526: "pdap-np", + 1527: "tlisrv", + 1528: "ngr-t", + 1529: "coauthor", + 1530: "rap-service", + 1531: "rap-listen", + 1532: "miroconnect", + 1533: "virtual-places", + 1534: "micromuse-lm", + 1535: "ampr-info", + 1536: "ampr-inter", + 1537: "sdsc-lm", + 1538: "3ds-lm", + 1539: "intellistor-lm", + 1540: "rds", + 1541: "rds2", + 1542: "gridgen-elmd", + 1543: "simba-cs", + 1544: "aspeclmd", + 1545: "vistium-share", + 1546: "abbaccuray", + 1547: "laplink", + 1548: "axon-lm", + 1549: "shivasound", + 1550: "3m-image-lm", + 1551: "hecmtl-db", + 1552: "pciarray", + 1553: "sna-cs", + 1554: "caci-lm", + 1555: "livelan", + 1556: "veritas-pbx", + 1557: "arbortext-lm", + 1558: "xingmpeg", + 1559: "web2host", + 1560: "asci-val", + 1561: "facilityview", + 1562: "pconnectmgr", + 1563: "cadabra-lm", + 1564: "pay-per-view", + 1565: "winddlb", + 1566: "corelvideo", + 1567: "jlicelmd", + 1568: "tsspmap", + 1569: "ets", + 1570: "orbixd", + 1571: "rdb-dbs-disp", + 1572: "chip-lm", + 1573: "itscomm-ns", + 1574: "mvel-lm", + 1575: "oraclenames", + 1576: "moldflow-lm", + 1577: "hypercube-lm", + 1578: "jacobus-lm", + 1579: "ioc-sea-lm", + 1580: "tn-tl-r2", + 1581: "mil-2045-47001", + 1582: "msims", + 1583: "simbaexpress", + 1584: "tn-tl-fd2", + 1585: "intv", + 1586: "ibm-abtact", + 1587: "pra-elmd", + 1588: "triquest-lm", + 1589: "vqp", + 1590: "gemini-lm", + 1591: "ncpm-pm", + 1592: "commonspace", + 1593: "mainsoft-lm", + 1594: "sixtrak", + 1595: "radio", + 1596: "radio-bc", + 1597: "orbplus-iiop", + 1598: "picknfs", + 1599: "simbaservices", + 1600: "issd", + 1601: "aas", + 1602: "inspect", + 1603: "picodbc", + 1604: "icabrowser", + 1605: "slp", + 1606: "slm-api", + 1607: "stt", + 1608: "smart-lm", + 1609: "isysg-lm", + 1610: "taurus-wh", + 1611: "ill", + 1612: "netbill-trans", + 1613: "netbill-keyrep", + 1614: "netbill-cred", + 1615: "netbill-auth", + 1616: "netbill-prod", + 1617: "nimrod-agent", + 1618: "skytelnet", + 1619: "xs-openstorage", + 1620: "faxportwinport", + 1621: "softdataphone", + 1622: "ontime", + 1623: "jaleosnd", + 1624: "udp-sr-port", + 1625: "svs-omagent", + 1626: "shockwave", + 1627: "t128-gateway", + 1628: "lontalk-norm", + 1629: "lontalk-urgnt", + 1630: "oraclenet8cman", + 1631: "visitview", + 1632: "pammratc", + 1633: "pammrpc", + 1634: "loaprobe", + 1635: "edb-server1", + 1636: "isdc", + 1637: "islc", + 1638: "ismc", + 1639: "cert-initiator", + 1640: "cert-responder", + 1641: "invision", + 1642: "isis-am", + 1643: "isis-ambc", + 1644: "saiseh", + 1645: "sightline", + 1646: "sa-msg-port", + 1647: "rsap", + 1648: "concurrent-lm", + 1649: "kermit", + 1650: "nkd", + 1651: "shiva-confsrvr", + 1652: "xnmp", + 1653: "alphatech-lm", + 1654: "stargatealerts", + 1655: "dec-mbadmin", + 1656: "dec-mbadmin-h", + 1657: "fujitsu-mmpdc", + 1658: "sixnetudr", + 1659: "sg-lm", + 1660: "skip-mc-gikreq", + 1661: "netview-aix-1", + 1662: "netview-aix-2", + 1663: "netview-aix-3", + 1664: "netview-aix-4", + 1665: "netview-aix-5", + 1666: "netview-aix-6", + 1667: "netview-aix-7", + 1668: "netview-aix-8", + 1669: "netview-aix-9", + 1670: "netview-aix-10", + 1671: "netview-aix-11", + 1672: "netview-aix-12", + 1673: "proshare-mc-1", + 1674: "proshare-mc-2", + 1675: "pdp", + 1676: "netcomm2", + 1677: "groupwise", + 1678: "prolink", + 1679: "darcorp-lm", + 1680: "microcom-sbp", + 1681: "sd-elmd", + 1682: "lanyon-lantern", + 1683: "ncpm-hip", + 1684: "snaresecure", + 1685: "n2nremote", + 1686: "cvmon", + 1687: "nsjtp-ctrl", + 1688: "nsjtp-data", + 1689: "firefox", + 1690: "ng-umds", + 1691: "empire-empuma", + 1692: "sstsys-lm", + 1693: "rrirtr", + 1694: "rrimwm", + 1695: "rrilwm", + 1696: "rrifmm", + 1697: "rrisat", + 1698: "rsvp-encap-1", + 1699: "rsvp-encap-2", + 1700: "mps-raft", + 1701: "l2f", + 1702: "deskshare", + 1703: "hb-engine", + 1704: "bcs-broker", + 1705: "slingshot", + 1706: "jetform", + 1707: "vdmplay", + 1708: "gat-lmd", + 1709: "centra", + 1710: "impera", + 1711: "pptconference", + 1712: "registrar", + 1713: "conferencetalk", + 1714: "sesi-lm", + 1715: "houdini-lm", + 1716: "xmsg", + 1717: "fj-hdnet", + 1718: "h323gatedisc", + 1719: "h323gatestat", + 1720: "h323hostcall", + 1721: "caicci", + 1722: "hks-lm", + 1723: "pptp", + 1724: "csbphonemaster", + 1725: "iden-ralp", + 1726: "iberiagames", + 1727: "winddx", + 1728: "telindus", + 1729: "citynl", + 1730: "roketz", + 1731: "msiccp", + 1732: "proxim", + 1733: "siipat", + 1734: "cambertx-lm", + 1735: "privatechat", + 1736: "street-stream", + 1737: "ultimad", + 1738: "gamegen1", + 1739: "webaccess", + 1740: "encore", + 1741: "cisco-net-mgmt", + 1742: "3Com-nsd", + 1743: "cinegrfx-lm", + 1744: "ncpm-ft", + 1745: "remote-winsock", + 1746: "ftrapid-1", + 1747: "ftrapid-2", + 1748: "oracle-em1", + 1749: "aspen-services", + 1750: "sslp", + 1751: "swiftnet", + 1752: "lofr-lm", + 1754: "oracle-em2", + 1755: "ms-streaming", + 1756: "capfast-lmd", + 1757: "cnhrp", + 1758: "tftp-mcast", + 1759: "spss-lm", + 1760: "www-ldap-gw", + 1761: "cft-0", + 1762: "cft-1", + 1763: "cft-2", + 1764: "cft-3", + 1765: "cft-4", + 1766: "cft-5", + 1767: "cft-6", + 1768: "cft-7", + 1769: "bmc-net-adm", + 1770: "bmc-net-svc", + 1771: "vaultbase", + 1772: "essweb-gw", + 1773: "kmscontrol", + 1774: "global-dtserv", + 1776: "femis", + 1777: "powerguardian", + 1778: "prodigy-intrnet", + 1779: "pharmasoft", + 1780: "dpkeyserv", + 1781: "answersoft-lm", + 1782: "hp-hcip", + 1784: "finle-lm", + 1785: "windlm", + 1786: "funk-logger", + 1787: "funk-license", + 1788: "psmond", + 1789: "hello", + 1790: "nmsp", + 1791: "ea1", + 1792: "ibm-dt-2", + 1793: "rsc-robot", + 1794: "cera-bcm", + 1795: "dpi-proxy", + 1796: "vocaltec-admin", + 1797: "uma", + 1798: "etp", + 1799: "netrisk", + 1800: "ansys-lm", + 1801: "msmq", + 1802: "concomp1", + 1803: "hp-hcip-gwy", + 1804: "enl", + 1805: "enl-name", + 1806: "musiconline", + 1807: "fhsp", + 1808: "oracle-vp2", + 1809: "oracle-vp1", + 1810: "jerand-lm", + 1811: "scientia-sdb", + 1812: "radius", + 1813: "radius-acct", + 1814: "tdp-suite", + 1815: "mmpft", + 1816: "harp", + 1817: "rkb-oscs", + 1818: "etftp", + 1819: "plato-lm", + 1820: "mcagent", + 1821: "donnyworld", + 1822: "es-elmd", + 1823: "unisys-lm", + 1824: "metrics-pas", + 1825: "direcpc-video", + 1826: "ardt", + 1827: "asi", + 1828: "itm-mcell-u", + 1829: "optika-emedia", + 1830: "net8-cman", + 1831: "myrtle", + 1832: "tht-treasure", + 1833: "udpradio", + 1834: "ardusuni", + 1835: "ardusmul", + 1836: "ste-smsc", + 1837: "csoft1", + 1838: "talnet", + 1839: "netopia-vo1", + 1840: "netopia-vo2", + 1841: "netopia-vo3", + 1842: "netopia-vo4", + 1843: "netopia-vo5", + 1844: "direcpc-dll", + 1845: "altalink", + 1846: "tunstall-pnc", + 1847: "slp-notify", + 1848: "fjdocdist", + 1849: "alpha-sms", + 1850: "gsi", + 1851: "ctcd", + 1852: "virtual-time", + 1853: "vids-avtp", + 1854: "buddy-draw", + 1855: "fiorano-rtrsvc", + 1856: "fiorano-msgsvc", + 1857: "datacaptor", + 1858: "privateark", + 1859: "gammafetchsvr", + 1860: "sunscalar-svc", + 1861: "lecroy-vicp", + 1862: "mysql-cm-agent", + 1863: "msnp", + 1864: "paradym-31port", + 1865: "entp", + 1866: "swrmi", + 1867: "udrive", + 1868: "viziblebrowser", + 1869: "transact", + 1870: "sunscalar-dns", + 1871: "canocentral0", + 1872: "canocentral1", + 1873: "fjmpjps", + 1874: "fjswapsnp", + 1875: "westell-stats", + 1876: "ewcappsrv", + 1877: "hp-webqosdb", + 1878: "drmsmc", + 1879: "nettgain-nms", + 1880: "vsat-control", + 1881: "ibm-mqseries2", + 1882: "ecsqdmn", + 1883: "mqtt", + 1884: "idmaps", + 1885: "vrtstrapserver", + 1886: "leoip", + 1887: "filex-lport", + 1888: "ncconfig", + 1889: "unify-adapter", + 1890: "wilkenlistener", + 1891: "childkey-notif", + 1892: "childkey-ctrl", + 1893: "elad", + 1894: "o2server-port", + 1896: "b-novative-ls", + 1897: "metaagent", + 1898: "cymtec-port", + 1899: "mc2studios", + 1900: "ssdp", + 1901: "fjicl-tep-a", + 1902: "fjicl-tep-b", + 1903: "linkname", + 1904: "fjicl-tep-c", + 1905: "sugp", + 1906: "tpmd", + 1907: "intrastar", + 1908: "dawn", + 1909: "global-wlink", + 1910: "ultrabac", + 1911: "mtp", + 1912: "rhp-iibp", + 1913: "armadp", + 1914: "elm-momentum", + 1915: "facelink", + 1916: "persona", + 1917: "noagent", + 1918: "can-nds", + 1919: "can-dch", + 1920: "can-ferret", + 1921: "noadmin", + 1922: "tapestry", + 1923: "spice", + 1924: "xiip", + 1925: "discovery-port", + 1926: "egs", + 1927: "videte-cipc", + 1928: "emsd-port", + 1929: "bandwiz-system", + 1930: "driveappserver", + 1931: "amdsched", + 1932: "ctt-broker", + 1933: "xmapi", + 1934: "xaapi", + 1935: "macromedia-fcs", + 1936: "jetcmeserver", + 1937: "jwserver", + 1938: "jwclient", + 1939: "jvserver", + 1940: "jvclient", + 1941: "dic-aida", + 1942: "res", + 1943: "beeyond-media", + 1944: "close-combat", + 1945: "dialogic-elmd", + 1946: "tekpls", + 1947: "sentinelsrm", + 1948: "eye2eye", + 1949: "ismaeasdaqlive", + 1950: "ismaeasdaqtest", + 1951: "bcs-lmserver", + 1952: "mpnjsc", + 1953: "rapidbase", + 1954: "abr-api", + 1955: "abr-secure", + 1956: "vrtl-vmf-ds", + 1957: "unix-status", + 1958: "dxadmind", + 1959: "simp-all", + 1960: "nasmanager", + 1961: "bts-appserver", + 1962: "biap-mp", + 1963: "webmachine", + 1964: "solid-e-engine", + 1965: "tivoli-npm", + 1966: "slush", + 1967: "sns-quote", + 1968: "lipsinc", + 1969: "lipsinc1", + 1970: "netop-rc", + 1971: "netop-school", + 1972: "intersys-cache", + 1973: "dlsrap", + 1974: "drp", + 1975: "tcoflashagent", + 1976: "tcoregagent", + 1977: "tcoaddressbook", + 1978: "unisql", + 1979: "unisql-java", + 1980: "pearldoc-xact", + 1981: "p2pq", + 1982: "estamp", + 1983: "lhtp", + 1984: "bb", + 1985: "hsrp", + 1986: "licensedaemon", + 1987: "tr-rsrb-p1", + 1988: "tr-rsrb-p2", + 1989: "tr-rsrb-p3", + 1990: "stun-p1", + 1991: "stun-p2", + 1992: "stun-p3", + 1993: "snmp-tcp-port", + 1994: "stun-port", + 1995: "perf-port", + 1996: "tr-rsrb-port", + 1997: "gdp-port", + 1998: "x25-svc-port", + 1999: "tcp-id-port", + 2000: "cisco-sccp", + 2001: "wizard", + 2002: "globe", + 2003: "brutus", + 2004: "emce", + 2005: "oracle", + 2006: "raid-cd", + 2007: "raid-am", + 2008: "terminaldb", + 2009: "whosockami", + 2010: "pipe-server", + 2011: "servserv", + 2012: "raid-ac", + 2013: "raid-cd", + 2014: "raid-sf", + 2015: "raid-cs", + 2016: "bootserver", + 2017: "bootclient", + 2018: "rellpack", + 2019: "about", + 2020: "xinupageserver", + 2021: "xinuexpansion1", + 2022: "xinuexpansion2", + 2023: "xinuexpansion3", + 2024: "xinuexpansion4", + 2025: "xribs", + 2026: "scrabble", + 2027: "shadowserver", + 2028: "submitserver", + 2029: "hsrpv6", + 2030: "device2", + 2031: "mobrien-chat", + 2032: "blackboard", + 2033: "glogger", + 2034: "scoremgr", + 2035: "imsldoc", + 2036: "e-dpnet", + 2037: "applus", + 2038: "objectmanager", + 2039: "prizma", + 2040: "lam", + 2041: "interbase", + 2042: "isis", + 2043: "isis-bcast", + 2044: "rimsl", + 2045: "cdfunc", + 2046: "sdfunc", + 2047: "dls", + 2048: "dls-monitor", + 2049: "shilp", + 2050: "av-emb-config", + 2051: "epnsdp", + 2052: "clearvisn", + 2053: "lot105-ds-upd", + 2054: "weblogin", + 2055: "iop", + 2056: "omnisky", + 2057: "rich-cp", + 2058: "newwavesearch", + 2059: "bmc-messaging", + 2060: "teleniumdaemon", + 2061: "netmount", + 2062: "icg-swp", + 2063: "icg-bridge", + 2064: "icg-iprelay", + 2065: "dlsrpn", + 2066: "aura", + 2067: "dlswpn", + 2068: "avauthsrvprtcl", + 2069: "event-port", + 2070: "ah-esp-encap", + 2071: "acp-port", + 2072: "msync", + 2073: "gxs-data-port", + 2074: "vrtl-vmf-sa", + 2075: "newlixengine", + 2076: "newlixconfig", + 2077: "tsrmagt", + 2078: "tpcsrvr", + 2079: "idware-router", + 2080: "autodesk-nlm", + 2081: "kme-trap-port", + 2082: "infowave", + 2083: "radsec", + 2084: "sunclustergeo", + 2085: "ada-cip", + 2086: "gnunet", + 2087: "eli", + 2088: "ip-blf", + 2089: "sep", + 2090: "lrp", + 2091: "prp", + 2092: "descent3", + 2093: "nbx-cc", + 2094: "nbx-au", + 2095: "nbx-ser", + 2096: "nbx-dir", + 2097: "jetformpreview", + 2098: "dialog-port", + 2099: "h2250-annex-g", + 2100: "amiganetfs", + 2101: "rtcm-sc104", + 2102: "zephyr-srv", + 2103: "zephyr-clt", + 2104: "zephyr-hm", + 2105: "minipay", + 2106: "mzap", + 2107: "bintec-admin", + 2108: "comcam", + 2109: "ergolight", + 2110: "umsp", + 2111: "dsatp", + 2112: "idonix-metanet", + 2113: "hsl-storm", + 2114: "newheights", + 2115: "kdm", + 2116: "ccowcmr", + 2117: "mentaclient", + 2118: "mentaserver", + 2119: "gsigatekeeper", + 2120: "qencp", + 2121: "scientia-ssdb", + 2122: "caupc-remote", + 2123: "gtp-control", + 2124: "elatelink", + 2125: "lockstep", + 2126: "pktcable-cops", + 2127: "index-pc-wb", + 2128: "net-steward", + 2129: "cs-live", + 2130: "xds", + 2131: "avantageb2b", + 2132: "solera-epmap", + 2133: "zymed-zpp", + 2134: "avenue", + 2135: "gris", + 2136: "appworxsrv", + 2137: "connect", + 2138: "unbind-cluster", + 2139: "ias-auth", + 2140: "ias-reg", + 2141: "ias-admind", + 2142: "tdmoip", + 2143: "lv-jc", + 2144: "lv-ffx", + 2145: "lv-pici", + 2146: "lv-not", + 2147: "lv-auth", + 2148: "veritas-ucl", + 2149: "acptsys", + 2150: "dynamic3d", + 2151: "docent", + 2152: "gtp-user", + 2153: "ctlptc", + 2154: "stdptc", + 2155: "brdptc", + 2156: "trp", + 2157: "xnds", + 2158: "touchnetplus", + 2159: "gdbremote", + 2160: "apc-2160", + 2161: "apc-2161", + 2162: "navisphere", + 2163: "navisphere-sec", + 2164: "ddns-v3", + 2165: "x-bone-api", + 2166: "iwserver", + 2167: "raw-serial", + 2168: "easy-soft-mux", + 2169: "brain", + 2170: "eyetv", + 2171: "msfw-storage", + 2172: "msfw-s-storage", + 2173: "msfw-replica", + 2174: "msfw-array", + 2175: "airsync", + 2176: "rapi", + 2177: "qwave", + 2178: "bitspeer", + 2179: "vmrdp", + 2180: "mc-gt-srv", + 2181: "eforward", + 2182: "cgn-stat", + 2183: "cgn-config", + 2184: "nvd", + 2185: "onbase-dds", + 2186: "gtaua", + 2187: "ssmd", + 2190: "tivoconnect", + 2191: "tvbus", + 2192: "asdis", + 2193: "drwcs", + 2197: "mnp-exchange", + 2198: "onehome-remote", + 2199: "onehome-help", + 2200: "ici", + 2201: "ats", + 2202: "imtc-map", + 2203: "b2-runtime", + 2204: "b2-license", + 2205: "jps", + 2206: "hpocbus", + 2207: "hpssd", + 2208: "hpiod", + 2209: "rimf-ps", + 2210: "noaaport", + 2211: "emwin", + 2212: "leecoposserver", + 2213: "kali", + 2214: "rpi", + 2215: "ipcore", + 2216: "vtu-comms", + 2217: "gotodevice", + 2218: "bounzza", + 2219: "netiq-ncap", + 2220: "netiq", + 2221: "ethernet-ip-s", + 2222: "EtherNet-IP-1", + 2223: "rockwell-csp2", + 2224: "efi-mg", + 2226: "di-drm", + 2227: "di-msg", + 2228: "ehome-ms", + 2229: "datalens", + 2230: "queueadm", + 2231: "wimaxasncp", + 2232: "ivs-video", + 2233: "infocrypt", + 2234: "directplay", + 2235: "sercomm-wlink", + 2236: "nani", + 2237: "optech-port1-lm", + 2238: "aviva-sna", + 2239: "imagequery", + 2240: "recipe", + 2241: "ivsd", + 2242: "foliocorp", + 2243: "magicom", + 2244: "nmsserver", + 2245: "hao", + 2246: "pc-mta-addrmap", + 2247: "antidotemgrsvr", + 2248: "ums", + 2249: "rfmp", + 2250: "remote-collab", + 2251: "dif-port", + 2252: "njenet-ssl", + 2253: "dtv-chan-req", + 2254: "seispoc", + 2255: "vrtp", + 2256: "pcc-mfp", + 2257: "simple-tx-rx", + 2258: "rcts", + 2260: "apc-2260", + 2261: "comotionmaster", + 2262: "comotionback", + 2263: "ecwcfg", + 2264: "apx500api-1", + 2265: "apx500api-2", + 2266: "mfserver", + 2267: "ontobroker", + 2268: "amt", + 2269: "mikey", + 2270: "starschool", + 2271: "mmcals", + 2272: "mmcal", + 2273: "mysql-im", + 2274: "pcttunnell", + 2275: "ibridge-data", + 2276: "ibridge-mgmt", + 2277: "bluectrlproxy", + 2278: "s3db", + 2279: "xmquery", + 2280: "lnvpoller", + 2281: "lnvconsole", + 2282: "lnvalarm", + 2283: "lnvstatus", + 2284: "lnvmaps", + 2285: "lnvmailmon", + 2286: "nas-metering", + 2287: "dna", + 2288: "netml", + 2289: "dict-lookup", + 2290: "sonus-logging", + 2291: "eapsp", + 2292: "mib-streaming", + 2293: "npdbgmngr", + 2294: "konshus-lm", + 2295: "advant-lm", + 2296: "theta-lm", + 2297: "d2k-datamover1", + 2298: "d2k-datamover2", + 2299: "pc-telecommute", + 2300: "cvmmon", + 2301: "cpq-wbem", + 2302: "binderysupport", + 2303: "proxy-gateway", + 2304: "attachmate-uts", + 2305: "mt-scaleserver", + 2306: "tappi-boxnet", + 2307: "pehelp", + 2308: "sdhelp", + 2309: "sdserver", + 2310: "sdclient", + 2311: "messageservice", + 2312: "wanscaler", + 2313: "iapp", + 2314: "cr-websystems", + 2315: "precise-sft", + 2316: "sent-lm", + 2317: "attachmate-g32", + 2318: "cadencecontrol", + 2319: "infolibria", + 2320: "siebel-ns", + 2321: "rdlap", + 2322: "ofsd", + 2323: "3d-nfsd", + 2324: "cosmocall", + 2325: "ansysli", + 2326: "idcp", + 2327: "xingcsm", + 2328: "netrix-sftm", + 2329: "nvd", + 2330: "tscchat", + 2331: "agentview", + 2332: "rcc-host", + 2333: "snapp", + 2334: "ace-client", + 2335: "ace-proxy", + 2336: "appleugcontrol", + 2337: "ideesrv", + 2338: "norton-lambert", + 2339: "3com-webview", + 2340: "wrs-registry", + 2341: "xiostatus", + 2342: "manage-exec", + 2343: "nati-logos", + 2344: "fcmsys", + 2345: "dbm", + 2346: "redstorm-join", + 2347: "redstorm-find", + 2348: "redstorm-info", + 2349: "redstorm-diag", + 2350: "psbserver", + 2351: "psrserver", + 2352: "pslserver", + 2353: "pspserver", + 2354: "psprserver", + 2355: "psdbserver", + 2356: "gxtelmd", + 2357: "unihub-server", + 2358: "futrix", + 2359: "flukeserver", + 2360: "nexstorindltd", + 2361: "tl1", + 2362: "digiman", + 2363: "mediacntrlnfsd", + 2364: "oi-2000", + 2365: "dbref", + 2366: "qip-login", + 2367: "service-ctrl", + 2368: "opentable", + 2370: "l3-hbmon", + 2372: "lanmessenger", + 2381: "compaq-https", + 2382: "ms-olap3", + 2383: "ms-olap4", + 2384: "sd-capacity", + 2385: "sd-data", + 2386: "virtualtape", + 2387: "vsamredirector", + 2388: "mynahautostart", + 2389: "ovsessionmgr", + 2390: "rsmtp", + 2391: "3com-net-mgmt", + 2392: "tacticalauth", + 2393: "ms-olap1", + 2394: "ms-olap2", + 2395: "lan900-remote", + 2396: "wusage", + 2397: "ncl", + 2398: "orbiter", + 2399: "fmpro-fdal", + 2400: "opequus-server", + 2401: "cvspserver", + 2402: "taskmaster2000", + 2403: "taskmaster2000", + 2404: "iec-104", + 2405: "trc-netpoll", + 2406: "jediserver", + 2407: "orion", + 2409: "sns-protocol", + 2410: "vrts-registry", + 2411: "netwave-ap-mgmt", + 2412: "cdn", + 2413: "orion-rmi-reg", + 2414: "beeyond", + 2415: "codima-rtp", + 2416: "rmtserver", + 2417: "composit-server", + 2418: "cas", + 2419: "attachmate-s2s", + 2420: "dslremote-mgmt", + 2421: "g-talk", + 2422: "crmsbits", + 2423: "rnrp", + 2424: "kofax-svr", + 2425: "fjitsuappmgr", + 2426: "vcmp", + 2427: "mgcp-gateway", + 2428: "ott", + 2429: "ft-role", + 2430: "venus", + 2431: "venus-se", + 2432: "codasrv", + 2433: "codasrv-se", + 2434: "pxc-epmap", + 2435: "optilogic", + 2436: "topx", + 2437: "unicontrol", + 2438: "msp", + 2439: "sybasedbsynch", + 2440: "spearway", + 2441: "pvsw-inet", + 2442: "netangel", + 2443: "powerclientcsf", + 2444: "btpp2sectrans", + 2445: "dtn1", + 2446: "bues-service", + 2447: "ovwdb", + 2448: "hpppssvr", + 2449: "ratl", + 2450: "netadmin", + 2451: "netchat", + 2452: "snifferclient", + 2453: "madge-ltd", + 2454: "indx-dds", + 2455: "wago-io-system", + 2456: "altav-remmgt", + 2457: "rapido-ip", + 2458: "griffin", + 2459: "community", + 2460: "ms-theater", + 2461: "qadmifoper", + 2462: "qadmifevent", + 2463: "lsi-raid-mgmt", + 2464: "direcpc-si", + 2465: "lbm", + 2466: "lbf", + 2467: "high-criteria", + 2468: "qip-msgd", + 2469: "mti-tcs-comm", + 2470: "taskman-port", + 2471: "seaodbc", + 2472: "c3", + 2473: "aker-cdp", + 2474: "vitalanalysis", + 2475: "ace-server", + 2476: "ace-svr-prop", + 2477: "ssm-cvs", + 2478: "ssm-cssps", + 2479: "ssm-els", + 2480: "powerexchange", + 2481: "giop", + 2482: "giop-ssl", + 2483: "ttc", + 2484: "ttc-ssl", + 2485: "netobjects1", + 2486: "netobjects2", + 2487: "pns", + 2488: "moy-corp", + 2489: "tsilb", + 2490: "qip-qdhcp", + 2491: "conclave-cpp", + 2492: "groove", + 2493: "talarian-mqs", + 2494: "bmc-ar", + 2495: "fast-rem-serv", + 2496: "dirgis", + 2497: "quaddb", + 2498: "odn-castraq", + 2499: "unicontrol", + 2500: "rtsserv", + 2501: "rtsclient", + 2502: "kentrox-prot", + 2503: "nms-dpnss", + 2504: "wlbs", + 2505: "ppcontrol", + 2506: "jbroker", + 2507: "spock", + 2508: "jdatastore", + 2509: "fjmpss", + 2510: "fjappmgrbulk", + 2511: "metastorm", + 2512: "citrixima", + 2513: "citrixadmin", + 2514: "facsys-ntp", + 2515: "facsys-router", + 2516: "maincontrol", + 2517: "call-sig-trans", + 2518: "willy", + 2519: "globmsgsvc", + 2520: "pvsw", + 2521: "adaptecmgr", + 2522: "windb", + 2523: "qke-llc-v3", + 2524: "optiwave-lm", + 2525: "ms-v-worlds", + 2526: "ema-sent-lm", + 2527: "iqserver", + 2528: "ncr-ccl", + 2529: "utsftp", + 2530: "vrcommerce", + 2531: "ito-e-gui", + 2532: "ovtopmd", + 2533: "snifferserver", + 2534: "combox-web-acc", + 2535: "madcap", + 2536: "btpp2audctr1", + 2537: "upgrade", + 2538: "vnwk-prapi", + 2539: "vsiadmin", + 2540: "lonworks", + 2541: "lonworks2", + 2542: "udrawgraph", + 2543: "reftek", + 2544: "novell-zen", + 2545: "sis-emt", + 2546: "vytalvaultbrtp", + 2547: "vytalvaultvsmp", + 2548: "vytalvaultpipe", + 2549: "ipass", + 2550: "ads", + 2551: "isg-uda-server", + 2552: "call-logging", + 2553: "efidiningport", + 2554: "vcnet-link-v10", + 2555: "compaq-wcp", + 2556: "nicetec-nmsvc", + 2557: "nicetec-mgmt", + 2558: "pclemultimedia", + 2559: "lstp", + 2560: "labrat", + 2561: "mosaixcc", + 2562: "delibo", + 2563: "cti-redwood", + 2564: "hp-3000-telnet", + 2565: "coord-svr", + 2566: "pcs-pcw", + 2567: "clp", + 2568: "spamtrap", + 2569: "sonuscallsig", + 2570: "hs-port", + 2571: "cecsvc", + 2572: "ibp", + 2573: "trustestablish", + 2574: "blockade-bpsp", + 2575: "hl7", + 2576: "tclprodebugger", + 2577: "scipticslsrvr", + 2578: "rvs-isdn-dcp", + 2579: "mpfoncl", + 2580: "tributary", + 2581: "argis-te", + 2582: "argis-ds", + 2583: "mon", + 2584: "cyaserv", + 2585: "netx-server", + 2586: "netx-agent", + 2587: "masc", + 2588: "privilege", + 2589: "quartus-tcl", + 2590: "idotdist", + 2591: "maytagshuffle", + 2592: "netrek", + 2593: "mns-mail", + 2594: "dts", + 2595: "worldfusion1", + 2596: "worldfusion2", + 2597: "homesteadglory", + 2598: "citriximaclient", + 2599: "snapd", + 2600: "hpstgmgr", + 2601: "discp-client", + 2602: "discp-server", + 2603: "servicemeter", + 2604: "nsc-ccs", + 2605: "nsc-posa", + 2606: "netmon", + 2607: "connection", + 2608: "wag-service", + 2609: "system-monitor", + 2610: "versa-tek", + 2611: "lionhead", + 2612: "qpasa-agent", + 2613: "smntubootstrap", + 2614: "neveroffline", + 2615: "firepower", + 2616: "appswitch-emp", + 2617: "cmadmin", + 2618: "priority-e-com", + 2619: "bruce", + 2620: "lpsrecommender", + 2621: "miles-apart", + 2622: "metricadbc", + 2623: "lmdp", + 2624: "aria", + 2625: "blwnkl-port", + 2626: "gbjd816", + 2627: "moshebeeri", + 2628: "dict", + 2629: "sitaraserver", + 2630: "sitaramgmt", + 2631: "sitaradir", + 2632: "irdg-post", + 2633: "interintelli", + 2634: "pk-electronics", + 2635: "backburner", + 2636: "solve", + 2637: "imdocsvc", + 2638: "sybaseanywhere", + 2639: "aminet", + 2640: "ami-control", + 2641: "hdl-srv", + 2642: "tragic", + 2643: "gte-samp", + 2644: "travsoft-ipx-t", + 2645: "novell-ipx-cmd", + 2646: "and-lm", + 2647: "syncserver", + 2648: "upsnotifyprot", + 2649: "vpsipport", + 2650: "eristwoguns", + 2651: "ebinsite", + 2652: "interpathpanel", + 2653: "sonus", + 2654: "corel-vncadmin", + 2655: "unglue", + 2656: "kana", + 2657: "sns-dispatcher", + 2658: "sns-admin", + 2659: "sns-query", + 2660: "gcmonitor", + 2661: "olhost", + 2662: "bintec-capi", + 2663: "bintec-tapi", + 2664: "patrol-mq-gm", + 2665: "patrol-mq-nm", + 2666: "extensis", + 2667: "alarm-clock-s", + 2668: "alarm-clock-c", + 2669: "toad", + 2670: "tve-announce", + 2671: "newlixreg", + 2672: "nhserver", + 2673: "firstcall42", + 2674: "ewnn", + 2675: "ttc-etap", + 2676: "simslink", + 2677: "gadgetgate1way", + 2678: "gadgetgate2way", + 2679: "syncserverssl", + 2680: "pxc-sapxom", + 2681: "mpnjsomb", + 2683: "ncdloadbalance", + 2684: "mpnjsosv", + 2685: "mpnjsocl", + 2686: "mpnjsomg", + 2687: "pq-lic-mgmt", + 2688: "md-cg-http", + 2689: "fastlynx", + 2690: "hp-nnm-data", + 2691: "itinternet", + 2692: "admins-lms", + 2694: "pwrsevent", + 2695: "vspread", + 2696: "unifyadmin", + 2697: "oce-snmp-trap", + 2698: "mck-ivpip", + 2699: "csoft-plusclnt", + 2700: "tqdata", + 2701: "sms-rcinfo", + 2702: "sms-xfer", + 2703: "sms-chat", + 2704: "sms-remctrl", + 2705: "sds-admin", + 2706: "ncdmirroring", + 2707: "emcsymapiport", + 2708: "banyan-net", + 2709: "supermon", + 2710: "sso-service", + 2711: "sso-control", + 2712: "aocp", + 2713: "raventbs", + 2714: "raventdm", + 2715: "hpstgmgr2", + 2716: "inova-ip-disco", + 2717: "pn-requester", + 2718: "pn-requester2", + 2719: "scan-change", + 2720: "wkars", + 2721: "smart-diagnose", + 2722: "proactivesrvr", + 2723: "watchdog-nt", + 2724: "qotps", + 2725: "msolap-ptp2", + 2726: "tams", + 2727: "mgcp-callagent", + 2728: "sqdr", + 2729: "tcim-control", + 2730: "nec-raidplus", + 2731: "fyre-messanger", + 2732: "g5m", + 2733: "signet-ctf", + 2734: "ccs-software", + 2735: "netiq-mc", + 2736: "radwiz-nms-srv", + 2737: "srp-feedback", + 2738: "ndl-tcp-ois-gw", + 2739: "tn-timing", + 2740: "alarm", + 2741: "tsb", + 2742: "tsb2", + 2743: "murx", + 2744: "honyaku", + 2745: "urbisnet", + 2746: "cpudpencap", + 2747: "fjippol-swrly", + 2748: "fjippol-polsvr", + 2749: "fjippol-cnsl", + 2750: "fjippol-port1", + 2751: "fjippol-port2", + 2752: "rsisysaccess", + 2753: "de-spot", + 2754: "apollo-cc", + 2755: "expresspay", + 2756: "simplement-tie", + 2757: "cnrp", + 2758: "apollo-status", + 2759: "apollo-gms", + 2760: "sabams", + 2761: "dicom-iscl", + 2762: "dicom-tls", + 2763: "desktop-dna", + 2764: "data-insurance", + 2765: "qip-audup", + 2766: "compaq-scp", + 2767: "uadtc", + 2768: "uacs", + 2769: "exce", + 2770: "veronica", + 2771: "vergencecm", + 2772: "auris", + 2773: "rbakcup1", + 2774: "rbakcup2", + 2775: "smpp", + 2776: "ridgeway1", + 2777: "ridgeway2", + 2778: "gwen-sonya", + 2779: "lbc-sync", + 2780: "lbc-control", + 2781: "whosells", + 2782: "everydayrc", + 2783: "aises", + 2784: "www-dev", + 2785: "aic-np", + 2786: "aic-oncrpc", + 2787: "piccolo", + 2788: "fryeserv", + 2789: "media-agent", + 2790: "plgproxy", + 2791: "mtport-regist", + 2792: "f5-globalsite", + 2793: "initlsmsad", + 2795: "livestats", + 2796: "ac-tech", + 2797: "esp-encap", + 2798: "tmesis-upshot", + 2799: "icon-discover", + 2800: "acc-raid", + 2801: "igcp", + 2802: "veritas-udp1", + 2803: "btprjctrl", + 2804: "dvr-esm", + 2805: "wta-wsp-s", + 2806: "cspuni", + 2807: "cspmulti", + 2808: "j-lan-p", + 2809: "corbaloc", + 2810: "netsteward", + 2811: "gsiftp", + 2812: "atmtcp", + 2813: "llm-pass", + 2814: "llm-csv", + 2815: "lbc-measure", + 2816: "lbc-watchdog", + 2817: "nmsigport", + 2818: "rmlnk", + 2819: "fc-faultnotify", + 2820: "univision", + 2821: "vrts-at-port", + 2822: "ka0wuc", + 2823: "cqg-netlan", + 2824: "cqg-netlan-1", + 2826: "slc-systemlog", + 2827: "slc-ctrlrloops", + 2828: "itm-lm", + 2829: "silkp1", + 2830: "silkp2", + 2831: "silkp3", + 2832: "silkp4", + 2833: "glishd", + 2834: "evtp", + 2835: "evtp-data", + 2836: "catalyst", + 2837: "repliweb", + 2838: "starbot", + 2839: "nmsigport", + 2840: "l3-exprt", + 2841: "l3-ranger", + 2842: "l3-hawk", + 2843: "pdnet", + 2844: "bpcp-poll", + 2845: "bpcp-trap", + 2846: "aimpp-hello", + 2847: "aimpp-port-req", + 2848: "amt-blc-port", + 2849: "fxp", + 2850: "metaconsole", + 2851: "webemshttp", + 2852: "bears-01", + 2853: "ispipes", + 2854: "infomover", + 2856: "cesdinv", + 2857: "simctlp", + 2858: "ecnp", + 2859: "activememory", + 2860: "dialpad-voice1", + 2861: "dialpad-voice2", + 2862: "ttg-protocol", + 2863: "sonardata", + 2864: "astromed-main", + 2865: "pit-vpn", + 2866: "iwlistener", + 2867: "esps-portal", + 2868: "npep-messaging", + 2869: "icslap", + 2870: "daishi", + 2871: "msi-selectplay", + 2872: "radix", + 2874: "dxmessagebase1", + 2875: "dxmessagebase2", + 2876: "sps-tunnel", + 2877: "bluelance", + 2878: "aap", + 2879: "ucentric-ds", + 2880: "synapse", + 2881: "ndsp", + 2882: "ndtp", + 2883: "ndnp", + 2884: "flashmsg", + 2885: "topflow", + 2886: "responselogic", + 2887: "aironetddp", + 2888: "spcsdlobby", + 2889: "rsom", + 2890: "cspclmulti", + 2891: "cinegrfx-elmd", + 2892: "snifferdata", + 2893: "vseconnector", + 2894: "abacus-remote", + 2895: "natuslink", + 2896: "ecovisiong6-1", + 2897: "citrix-rtmp", + 2898: "appliance-cfg", + 2899: "powergemplus", + 2900: "quicksuite", + 2901: "allstorcns", + 2902: "netaspi", + 2903: "suitcase", + 2904: "m2ua", + 2906: "caller9", + 2907: "webmethods-b2b", + 2908: "mao", + 2909: "funk-dialout", + 2910: "tdaccess", + 2911: "blockade", + 2912: "epicon", + 2913: "boosterware", + 2914: "gamelobby", + 2915: "tksocket", + 2916: "elvin-server", + 2917: "elvin-client", + 2918: "kastenchasepad", + 2919: "roboer", + 2920: "roboeda", + 2921: "cesdcdman", + 2922: "cesdcdtrn", + 2923: "wta-wsp-wtp-s", + 2924: "precise-vip", + 2926: "mobile-file-dl", + 2927: "unimobilectrl", + 2928: "redstone-cpss", + 2929: "amx-webadmin", + 2930: "amx-weblinx", + 2931: "circle-x", + 2932: "incp", + 2933: "4-tieropmgw", + 2934: "4-tieropmcli", + 2935: "qtp", + 2936: "otpatch", + 2937: "pnaconsult-lm", + 2938: "sm-pas-1", + 2939: "sm-pas-2", + 2940: "sm-pas-3", + 2941: "sm-pas-4", + 2942: "sm-pas-5", + 2943: "ttnrepository", + 2944: "megaco-h248", + 2945: "h248-binary", + 2946: "fjsvmpor", + 2947: "gpsd", + 2948: "wap-push", + 2949: "wap-pushsecure", + 2950: "esip", + 2951: "ottp", + 2952: "mpfwsas", + 2953: "ovalarmsrv", + 2954: "ovalarmsrv-cmd", + 2955: "csnotify", + 2956: "ovrimosdbman", + 2957: "jmact5", + 2958: "jmact6", + 2959: "rmopagt", + 2960: "dfoxserver", + 2961: "boldsoft-lm", + 2962: "iph-policy-cli", + 2963: "iph-policy-adm", + 2964: "bullant-srap", + 2965: "bullant-rap", + 2966: "idp-infotrieve", + 2967: "ssc-agent", + 2968: "enpp", + 2969: "essp", + 2970: "index-net", + 2971: "netclip", + 2972: "pmsm-webrctl", + 2973: "svnetworks", + 2974: "signal", + 2975: "fjmpcm", + 2976: "cns-srv-port", + 2977: "ttc-etap-ns", + 2978: "ttc-etap-ds", + 2979: "h263-video", + 2980: "wimd", + 2981: "mylxamport", + 2982: "iwb-whiteboard", + 2983: "netplan", + 2984: "hpidsadmin", + 2985: "hpidsagent", + 2986: "stonefalls", + 2987: "identify", + 2988: "hippad", + 2989: "zarkov", + 2990: "boscap", + 2991: "wkstn-mon", + 2992: "avenyo", + 2993: "veritas-vis1", + 2994: "veritas-vis2", + 2995: "idrs", + 2996: "vsixml", + 2997: "rebol", + 2998: "realsecure", + 2999: "remoteware-un", + 3000: "hbci", + 3002: "exlm-agent", + 3003: "cgms", + 3004: "csoftragent", + 3005: "geniuslm", + 3006: "ii-admin", + 3007: "lotusmtap", + 3008: "midnight-tech", + 3009: "pxc-ntfy", + 3010: "ping-pong", + 3011: "trusted-web", + 3012: "twsdss", + 3013: "gilatskysurfer", + 3014: "broker-service", + 3015: "nati-dstp", + 3016: "notify-srvr", + 3017: "event-listener", + 3018: "srvc-registry", + 3019: "resource-mgr", + 3020: "cifs", + 3021: "agriserver", + 3022: "csregagent", + 3023: "magicnotes", + 3024: "nds-sso", + 3025: "arepa-raft", + 3026: "agri-gateway", + 3027: "LiebDevMgmt-C", + 3028: "LiebDevMgmt-DM", + 3029: "LiebDevMgmt-A", + 3030: "arepa-cas", + 3031: "eppc", + 3032: "redwood-chat", + 3033: "pdb", + 3034: "osmosis-aeea", + 3035: "fjsv-gssagt", + 3036: "hagel-dump", + 3037: "hp-san-mgmt", + 3038: "santak-ups", + 3039: "cogitate", + 3040: "tomato-springs", + 3041: "di-traceware", + 3042: "journee", + 3043: "brp", + 3044: "epp", + 3045: "responsenet", + 3046: "di-ase", + 3047: "hlserver", + 3048: "pctrader", + 3049: "nsws", + 3050: "gds-db", + 3051: "galaxy-server", + 3052: "apc-3052", + 3053: "dsom-server", + 3054: "amt-cnf-prot", + 3055: "policyserver", + 3056: "cdl-server", + 3057: "goahead-fldup", + 3058: "videobeans", + 3059: "qsoft", + 3060: "interserver", + 3061: "cautcpd", + 3062: "ncacn-ip-tcp", + 3063: "ncadg-ip-udp", + 3064: "rprt", + 3065: "slinterbase", + 3066: "netattachsdmp", + 3067: "fjhpjp", + 3068: "ls3bcast", + 3069: "ls3", + 3070: "mgxswitch", + 3072: "csd-monitor", + 3073: "vcrp", + 3074: "xbox", + 3075: "orbix-locator", + 3076: "orbix-config", + 3077: "orbix-loc-ssl", + 3078: "orbix-cfg-ssl", + 3079: "lv-frontpanel", + 3080: "stm-pproc", + 3081: "tl1-lv", + 3082: "tl1-raw", + 3083: "tl1-telnet", + 3084: "itm-mccs", + 3085: "pcihreq", + 3086: "jdl-dbkitchen", + 3087: "asoki-sma", + 3088: "xdtp", + 3089: "ptk-alink", + 3090: "stss", + 3091: "1ci-smcs", + 3093: "rapidmq-center", + 3094: "rapidmq-reg", + 3095: "panasas", + 3096: "ndl-aps", + 3098: "umm-port", + 3099: "chmd", + 3100: "opcon-xps", + 3101: "hp-pxpib", + 3102: "slslavemon", + 3103: "autocuesmi", + 3104: "autocuetime", + 3105: "cardbox", + 3106: "cardbox-http", + 3107: "business", + 3108: "geolocate", + 3109: "personnel", + 3110: "sim-control", + 3111: "wsynch", + 3112: "ksysguard", + 3113: "cs-auth-svr", + 3114: "ccmad", + 3115: "mctet-master", + 3116: "mctet-gateway", + 3117: "mctet-jserv", + 3118: "pkagent", + 3119: "d2000kernel", + 3120: "d2000webserver", + 3122: "vtr-emulator", + 3123: "edix", + 3124: "beacon-port", + 3125: "a13-an", + 3127: "ctx-bridge", + 3128: "ndl-aas", + 3129: "netport-id", + 3130: "icpv2", + 3131: "netbookmark", + 3132: "ms-rule-engine", + 3133: "prism-deploy", + 3134: "ecp", + 3135: "peerbook-port", + 3136: "grubd", + 3137: "rtnt-1", + 3138: "rtnt-2", + 3139: "incognitorv", + 3140: "ariliamulti", + 3141: "vmodem", + 3142: "rdc-wh-eos", + 3143: "seaview", + 3144: "tarantella", + 3145: "csi-lfap", + 3146: "bears-02", + 3147: "rfio", + 3148: "nm-game-admin", + 3149: "nm-game-server", + 3150: "nm-asses-admin", + 3151: "nm-assessor", + 3152: "feitianrockey", + 3153: "s8-client-port", + 3154: "ccmrmi", + 3155: "jpegmpeg", + 3156: "indura", + 3157: "e3consultants", + 3158: "stvp", + 3159: "navegaweb-port", + 3160: "tip-app-server", + 3161: "doc1lm", + 3162: "sflm", + 3163: "res-sap", + 3164: "imprs", + 3165: "newgenpay", + 3166: "sossecollector", + 3167: "nowcontact", + 3168: "poweronnud", + 3169: "serverview-as", + 3170: "serverview-asn", + 3171: "serverview-gf", + 3172: "serverview-rm", + 3173: "serverview-icc", + 3174: "armi-server", + 3175: "t1-e1-over-ip", + 3176: "ars-master", + 3177: "phonex-port", + 3178: "radclientport", + 3179: "h2gf-w-2m", + 3180: "mc-brk-srv", + 3181: "bmcpatrolagent", + 3182: "bmcpatrolrnvu", + 3183: "cops-tls", + 3184: "apogeex-port", + 3185: "smpppd", + 3186: "iiw-port", + 3187: "odi-port", + 3188: "brcm-comm-port", + 3189: "pcle-infex", + 3190: "csvr-proxy", + 3191: "csvr-sslproxy", + 3192: "firemonrcc", + 3193: "spandataport", + 3194: "magbind", + 3195: "ncu-1", + 3196: "ncu-2", + 3197: "embrace-dp-s", + 3198: "embrace-dp-c", + 3199: "dmod-workspace", + 3200: "tick-port", + 3201: "cpq-tasksmart", + 3202: "intraintra", + 3203: "netwatcher-mon", + 3204: "netwatcher-db", + 3205: "isns", + 3206: "ironmail", + 3207: "vx-auth-port", + 3208: "pfu-prcallback", + 3209: "netwkpathengine", + 3210: "flamenco-proxy", + 3211: "avsecuremgmt", + 3212: "surveyinst", + 3213: "neon24x7", + 3214: "jmq-daemon-1", + 3215: "jmq-daemon-2", + 3216: "ferrari-foam", + 3217: "unite", + 3218: "smartpackets", + 3219: "wms-messenger", + 3220: "xnm-ssl", + 3221: "xnm-clear-text", + 3222: "glbp", + 3223: "digivote", + 3224: "aes-discovery", + 3225: "fcip-port", + 3226: "isi-irp", + 3227: "dwnmshttp", + 3228: "dwmsgserver", + 3229: "global-cd-port", + 3230: "sftdst-port", + 3231: "vidigo", + 3232: "mdtp", + 3233: "whisker", + 3234: "alchemy", + 3235: "mdap-port", + 3236: "apparenet-ts", + 3237: "apparenet-tps", + 3238: "apparenet-as", + 3239: "apparenet-ui", + 3240: "triomotion", + 3241: "sysorb", + 3242: "sdp-id-port", + 3243: "timelot", + 3244: "onesaf", + 3245: "vieo-fe", + 3246: "dvt-system", + 3247: "dvt-data", + 3248: "procos-lm", + 3249: "ssp", + 3250: "hicp", + 3251: "sysscanner", + 3252: "dhe", + 3253: "pda-data", + 3254: "pda-sys", + 3255: "semaphore", + 3256: "cpqrpm-agent", + 3257: "cpqrpm-server", + 3258: "ivecon-port", + 3259: "epncdp2", + 3260: "iscsi-target", + 3261: "winshadow", + 3262: "necp", + 3263: "ecolor-imager", + 3264: "ccmail", + 3265: "altav-tunnel", + 3266: "ns-cfg-server", + 3267: "ibm-dial-out", + 3268: "msft-gc", + 3269: "msft-gc-ssl", + 3270: "verismart", + 3271: "csoft-prev", + 3272: "user-manager", + 3273: "sxmp", + 3274: "ordinox-server", + 3275: "samd", + 3276: "maxim-asics", + 3277: "awg-proxy", + 3278: "lkcmserver", + 3279: "admind", + 3280: "vs-server", + 3281: "sysopt", + 3282: "datusorb", + 3283: "Apple Remote Desktop (Net Assistant)", + 3284: "4talk", + 3285: "plato", + 3286: "e-net", + 3287: "directvdata", + 3288: "cops", + 3289: "enpc", + 3290: "caps-lm", + 3291: "sah-lm", + 3292: "cart-o-rama", + 3293: "fg-fps", + 3294: "fg-gip", + 3295: "dyniplookup", + 3296: "rib-slm", + 3297: "cytel-lm", + 3298: "deskview", + 3299: "pdrncs", + 3302: "mcs-fastmail", + 3303: "opsession-clnt", + 3304: "opsession-srvr", + 3305: "odette-ftp", + 3306: "mysql", + 3307: "opsession-prxy", + 3308: "tns-server", + 3309: "tns-adv", + 3310: "dyna-access", + 3311: "mcns-tel-ret", + 3312: "appman-server", + 3313: "uorb", + 3314: "uohost", + 3315: "cdid", + 3316: "aicc-cmi", + 3317: "vsaiport", + 3318: "ssrip", + 3319: "sdt-lmd", + 3320: "officelink2000", + 3321: "vnsstr", + 3326: "sftu", + 3327: "bbars", + 3328: "egptlm", + 3329: "hp-device-disc", + 3330: "mcs-calypsoicf", + 3331: "mcs-messaging", + 3332: "mcs-mailsvr", + 3333: "dec-notes", + 3334: "directv-web", + 3335: "directv-soft", + 3336: "directv-tick", + 3337: "directv-catlg", + 3338: "anet-b", + 3339: "anet-l", + 3340: "anet-m", + 3341: "anet-h", + 3342: "webtie", + 3343: "ms-cluster-net", + 3344: "bnt-manager", + 3345: "influence", + 3346: "trnsprntproxy", + 3347: "phoenix-rpc", + 3348: "pangolin-laser", + 3349: "chevinservices", + 3350: "findviatv", + 3351: "btrieve", + 3352: "ssql", + 3353: "fatpipe", + 3354: "suitjd", + 3355: "ordinox-dbase", + 3356: "upnotifyps", + 3357: "adtech-test", + 3358: "mpsysrmsvr", + 3359: "wg-netforce", + 3360: "kv-server", + 3361: "kv-agent", + 3362: "dj-ilm", + 3363: "nati-vi-server", + 3364: "creativeserver", + 3365: "contentserver", + 3366: "creativepartnr", + 3372: "tip2", + 3373: "lavenir-lm", + 3374: "cluster-disc", + 3375: "vsnm-agent", + 3376: "cdbroker", + 3377: "cogsys-lm", + 3378: "wsicopy", + 3379: "socorfs", + 3380: "sns-channels", + 3381: "geneous", + 3382: "fujitsu-neat", + 3383: "esp-lm", + 3384: "hp-clic", + 3385: "qnxnetman", + 3386: "gprs-sig", + 3387: "backroomnet", + 3388: "cbserver", + 3389: "ms-wbt-server", + 3390: "dsc", + 3391: "savant", + 3392: "efi-lm", + 3393: "d2k-tapestry1", + 3394: "d2k-tapestry2", + 3395: "dyna-lm", + 3396: "printer-agent", + 3397: "cloanto-lm", + 3398: "mercantile", + 3399: "csms", + 3400: "csms2", + 3401: "filecast", + 3402: "fxaengine-net", + 3405: "nokia-ann-ch1", + 3406: "nokia-ann-ch2", + 3407: "ldap-admin", + 3408: "BESApi", + 3409: "networklens", + 3410: "networklenss", + 3411: "biolink-auth", + 3412: "xmlblaster", + 3413: "svnet", + 3414: "wip-port", + 3415: "bcinameservice", + 3416: "commandport", + 3417: "csvr", + 3418: "rnmap", + 3419: "softaudit", + 3420: "ifcp-port", + 3421: "bmap", + 3422: "rusb-sys-port", + 3423: "xtrm", + 3424: "xtrms", + 3425: "agps-port", + 3426: "arkivio", + 3427: "websphere-snmp", + 3428: "twcss", + 3429: "gcsp", + 3430: "ssdispatch", + 3431: "ndl-als", + 3432: "osdcp", + 3433: "opnet-smp", + 3434: "opencm", + 3435: "pacom", + 3436: "gc-config", + 3437: "autocueds", + 3438: "spiral-admin", + 3439: "hri-port", + 3440: "ans-console", + 3441: "connect-client", + 3442: "connect-server", + 3443: "ov-nnm-websrv", + 3444: "denali-server", + 3445: "monp", + 3446: "3comfaxrpc", + 3447: "directnet", + 3448: "dnc-port", + 3449: "hotu-chat", + 3450: "castorproxy", + 3451: "asam", + 3452: "sabp-signal", + 3453: "pscupd", + 3454: "mira", + 3455: "prsvp", + 3456: "vat", + 3457: "vat-control", + 3458: "d3winosfi", + 3459: "integral", + 3460: "edm-manager", + 3461: "edm-stager", + 3462: "edm-std-notify", + 3463: "edm-adm-notify", + 3464: "edm-mgr-sync", + 3465: "edm-mgr-cntrl", + 3466: "workflow", + 3467: "rcst", + 3468: "ttcmremotectrl", + 3469: "pluribus", + 3470: "jt400", + 3471: "jt400-ssl", + 3472: "jaugsremotec-1", + 3473: "jaugsremotec-2", + 3474: "ttntspauto", + 3475: "genisar-port", + 3476: "nppmp", + 3477: "ecomm", + 3478: "stun", + 3479: "twrpc", + 3480: "plethora", + 3481: "cleanerliverc", + 3482: "vulture", + 3483: "slim-devices", + 3484: "gbs-stp", + 3485: "celatalk", + 3486: "ifsf-hb-port", + 3487: "ltcudp", + 3488: "fs-rh-srv", + 3489: "dtp-dia", + 3490: "colubris", + 3491: "swr-port", + 3492: "tvdumtray-port", + 3493: "nut", + 3494: "ibm3494", + 3495: "seclayer-tcp", + 3496: "seclayer-tls", + 3497: "ipether232port", + 3498: "dashpas-port", + 3499: "sccip-media", + 3500: "rtmp-port", + 3501: "isoft-p2p", + 3502: "avinstalldisc", + 3503: "lsp-ping", + 3504: "ironstorm", + 3505: "ccmcomm", + 3506: "apc-3506", + 3507: "nesh-broker", + 3508: "interactionweb", + 3509: "vt-ssl", + 3510: "xss-port", + 3511: "webmail-2", + 3512: "aztec", + 3513: "arcpd", + 3514: "must-p2p", + 3515: "must-backplane", + 3516: "smartcard-port", + 3517: "802-11-iapp", + 3518: "artifact-msg", + 3519: "galileo", + 3520: "galileolog", + 3521: "mc3ss", + 3522: "nssocketport", + 3523: "odeumservlink", + 3524: "ecmport", + 3525: "eisport", + 3526: "starquiz-port", + 3527: "beserver-msg-q", + 3528: "jboss-iiop", + 3529: "jboss-iiop-ssl", + 3530: "gf", + 3531: "joltid", + 3532: "raven-rmp", + 3533: "raven-rdp", + 3534: "urld-port", + 3535: "ms-la", + 3536: "snac", + 3537: "ni-visa-remote", + 3538: "ibm-diradm", + 3539: "ibm-diradm-ssl", + 3540: "pnrp-port", + 3541: "voispeed-port", + 3542: "hacl-monitor", + 3543: "qftest-lookup", + 3544: "teredo", + 3545: "camac", + 3547: "symantec-sim", + 3548: "interworld", + 3549: "tellumat-nms", + 3550: "ssmpp", + 3551: "apcupsd", + 3552: "taserver", + 3553: "rbr-discovery", + 3554: "questnotify", + 3555: "razor", + 3556: "sky-transport", + 3557: "personalos-001", + 3558: "mcp-port", + 3559: "cctv-port", + 3560: "iniserve-port", + 3561: "bmc-onekey", + 3562: "sdbproxy", + 3563: "watcomdebug", + 3564: "esimport", + 3567: "dof-eps", + 3568: "dof-tunnel-sec", + 3569: "mbg-ctrl", + 3570: "mccwebsvr-port", + 3571: "megardsvr-port", + 3572: "megaregsvrport", + 3573: "tag-ups-1", + 3574: "dmaf-caster", + 3575: "ccm-port", + 3576: "cmc-port", + 3577: "config-port", + 3578: "data-port", + 3579: "ttat3lb", + 3580: "nati-svrloc", + 3581: "kfxaclicensing", + 3582: "press", + 3583: "canex-watch", + 3584: "u-dbap", + 3585: "emprise-lls", + 3586: "emprise-lsc", + 3587: "p2pgroup", + 3588: "sentinel", + 3589: "isomair", + 3590: "wv-csp-sms", + 3591: "gtrack-server", + 3592: "gtrack-ne", + 3593: "bpmd", + 3594: "mediaspace", + 3595: "shareapp", + 3596: "iw-mmogame", + 3597: "a14", + 3598: "a15", + 3599: "quasar-server", + 3600: "trap-daemon", + 3601: "visinet-gui", + 3602: "infiniswitchcl", + 3603: "int-rcv-cntrl", + 3604: "bmc-jmx-port", + 3605: "comcam-io", + 3606: "splitlock", + 3607: "precise-i3", + 3608: "trendchip-dcp", + 3609: "cpdi-pidas-cm", + 3610: "echonet", + 3611: "six-degrees", + 3612: "hp-dataprotect", + 3613: "alaris-disc", + 3614: "sigma-port", + 3615: "start-network", + 3616: "cd3o-protocol", + 3617: "sharp-server", + 3618: "aairnet-1", + 3619: "aairnet-2", + 3620: "ep-pcp", + 3621: "ep-nsp", + 3622: "ff-lr-port", + 3623: "haipe-discover", + 3624: "dist-upgrade", + 3625: "volley", + 3626: "bvcdaemon-port", + 3627: "jamserverport", + 3628: "ept-machine", + 3629: "escvpnet", + 3630: "cs-remote-db", + 3631: "cs-services", + 3632: "distcc", + 3633: "wacp", + 3634: "hlibmgr", + 3635: "sdo", + 3636: "servistaitsm", + 3637: "scservp", + 3638: "ehp-backup", + 3639: "xap-ha", + 3640: "netplay-port1", + 3641: "netplay-port2", + 3642: "juxml-port", + 3643: "audiojuggler", + 3644: "ssowatch", + 3645: "cyc", + 3646: "xss-srv-port", + 3647: "splitlock-gw", + 3648: "fjcp", + 3649: "nmmp", + 3650: "prismiq-plugin", + 3651: "xrpc-registry", + 3652: "vxcrnbuport", + 3653: "tsp", + 3654: "vaprtm", + 3655: "abatemgr", + 3656: "abatjss", + 3657: "immedianet-bcn", + 3658: "ps-ams", + 3659: "apple-sasl", + 3660: "can-nds-ssl", + 3661: "can-ferret-ssl", + 3662: "pserver", + 3663: "dtp", + 3664: "ups-engine", + 3665: "ent-engine", + 3666: "eserver-pap", + 3667: "infoexch", + 3668: "dell-rm-port", + 3669: "casanswmgmt", + 3670: "smile", + 3671: "efcp", + 3672: "lispworks-orb", + 3673: "mediavault-gui", + 3674: "wininstall-ipc", + 3675: "calltrax", + 3676: "va-pacbase", + 3677: "roverlog", + 3678: "ipr-dglt", + 3679: "Escale (Newton Dock)", + 3680: "npds-tracker", + 3681: "bts-x73", + 3682: "cas-mapi", + 3683: "bmc-ea", + 3684: "faxstfx-port", + 3685: "dsx-agent", + 3686: "tnmpv2", + 3687: "simple-push", + 3688: "simple-push-s", + 3689: "daap", + 3690: "svn", + 3691: "magaya-network", + 3692: "intelsync", + 3695: "bmc-data-coll", + 3696: "telnetcpcd", + 3697: "nw-license", + 3698: "sagectlpanel", + 3699: "kpn-icw", + 3700: "lrs-paging", + 3701: "netcelera", + 3702: "ws-discovery", + 3703: "adobeserver-3", + 3704: "adobeserver-4", + 3705: "adobeserver-5", + 3706: "rt-event", + 3707: "rt-event-s", + 3708: "sun-as-iiops", + 3709: "ca-idms", + 3710: "portgate-auth", + 3711: "edb-server2", + 3712: "sentinel-ent", + 3713: "tftps", + 3714: "delos-dms", + 3715: "anoto-rendezv", + 3716: "wv-csp-sms-cir", + 3717: "wv-csp-udp-cir", + 3718: "opus-services", + 3719: "itelserverport", + 3720: "ufastro-instr", + 3721: "xsync", + 3722: "xserveraid", + 3723: "sychrond", + 3724: "blizwow", + 3725: "na-er-tip", + 3726: "array-manager", + 3727: "e-mdu", + 3728: "e-woa", + 3729: "fksp-audit", + 3730: "client-ctrl", + 3731: "smap", + 3732: "m-wnn", + 3733: "multip-msg", + 3734: "synel-data", + 3735: "pwdis", + 3736: "rs-rmi", + 3738: "versatalk", + 3739: "launchbird-lm", + 3740: "heartbeat", + 3741: "wysdma", + 3742: "cst-port", + 3743: "ipcs-command", + 3744: "sasg", + 3745: "gw-call-port", + 3746: "linktest", + 3747: "linktest-s", + 3748: "webdata", + 3749: "cimtrak", + 3750: "cbos-ip-port", + 3751: "gprs-cube", + 3752: "vipremoteagent", + 3753: "nattyserver", + 3754: "timestenbroker", + 3755: "sas-remote-hlp", + 3756: "canon-capt", + 3757: "grf-port", + 3758: "apw-registry", + 3759: "exapt-lmgr", + 3760: "adtempusclient", + 3761: "gsakmp", + 3762: "gbs-smp", + 3763: "xo-wave", + 3764: "mni-prot-rout", + 3765: "rtraceroute", + 3767: "listmgr-port", + 3768: "rblcheckd", + 3769: "haipe-otnk", + 3770: "cindycollab", + 3771: "paging-port", + 3772: "ctp", + 3773: "ctdhercules", + 3774: "zicom", + 3775: "ispmmgr", + 3776: "dvcprov-port", + 3777: "jibe-eb", + 3778: "c-h-it-port", + 3779: "cognima", + 3780: "nnp", + 3781: "abcvoice-port", + 3782: "iso-tp0s", + 3783: "bim-pem", + 3784: "bfd-control", + 3785: "bfd-echo", + 3786: "upstriggervsw", + 3787: "fintrx", + 3788: "isrp-port", + 3789: "remotedeploy", + 3790: "quickbooksrds", + 3791: "tvnetworkvideo", + 3792: "sitewatch", + 3793: "dcsoftware", + 3794: "jaus", + 3795: "myblast", + 3796: "spw-dialer", + 3797: "idps", + 3798: "minilock", + 3799: "radius-dynauth", + 3800: "pwgpsi", + 3801: "ibm-mgr", + 3802: "vhd", + 3803: "soniqsync", + 3804: "iqnet-port", + 3805: "tcpdataserver", + 3806: "wsmlb", + 3807: "spugna", + 3808: "sun-as-iiops-ca", + 3809: "apocd", + 3810: "wlanauth", + 3811: "amp", + 3812: "neto-wol-server", + 3813: "rap-ip", + 3814: "neto-dcs", + 3815: "lansurveyorxml", + 3816: "sunlps-http", + 3817: "tapeware", + 3818: "crinis-hb", + 3819: "epl-slp", + 3820: "scp", + 3821: "pmcp", + 3822: "acp-discovery", + 3823: "acp-conduit", + 3824: "acp-policy", + 3825: "ffserver", + 3826: "warmux", + 3827: "netmpi", + 3828: "neteh", + 3829: "neteh-ext", + 3830: "cernsysmgmtagt", + 3831: "dvapps", + 3832: "xxnetserver", + 3833: "aipn-auth", + 3834: "spectardata", + 3835: "spectardb", + 3836: "markem-dcp", + 3837: "mkm-discovery", + 3838: "sos", + 3839: "amx-rms", + 3840: "flirtmitmir", + 3842: "nhci", + 3843: "quest-agent", + 3844: "rnm", + 3845: "v-one-spp", + 3846: "an-pcp", + 3847: "msfw-control", + 3848: "item", + 3849: "spw-dnspreload", + 3850: "qtms-bootstrap", + 3851: "spectraport", + 3852: "sse-app-config", + 3853: "sscan", + 3854: "stryker-com", + 3855: "opentrac", + 3856: "informer", + 3857: "trap-port", + 3858: "trap-port-mom", + 3859: "nav-port", + 3860: "sasp", + 3861: "winshadow-hd", + 3862: "giga-pocket", + 3863: "asap-udp", + 3865: "xpl", + 3866: "dzdaemon", + 3867: "dzoglserver", + 3869: "ovsam-mgmt", + 3870: "ovsam-d-agent", + 3871: "avocent-adsap", + 3872: "oem-agent", + 3873: "fagordnc", + 3874: "sixxsconfig", + 3875: "pnbscada", + 3876: "dl-agent", + 3877: "xmpcr-interface", + 3878: "fotogcad", + 3879: "appss-lm", + 3880: "igrs", + 3881: "idac", + 3882: "msdts1", + 3883: "vrpn", + 3884: "softrack-meter", + 3885: "topflow-ssl", + 3886: "nei-management", + 3887: "ciphire-data", + 3888: "ciphire-serv", + 3889: "dandv-tester", + 3890: "ndsconnect", + 3891: "rtc-pm-port", + 3892: "pcc-image-port", + 3893: "cgi-starapi", + 3894: "syam-agent", + 3895: "syam-smc", + 3896: "sdo-tls", + 3897: "sdo-ssh", + 3898: "senip", + 3899: "itv-control", + 3900: "udt-os", + 3901: "nimsh", + 3902: "nimaux", + 3903: "charsetmgr", + 3904: "omnilink-port", + 3905: "mupdate", + 3906: "topovista-data", + 3907: "imoguia-port", + 3908: "hppronetman", + 3909: "surfcontrolcpa", + 3910: "prnrequest", + 3911: "prnstatus", + 3912: "gbmt-stars", + 3913: "listcrt-port", + 3914: "listcrt-port-2", + 3915: "agcat", + 3916: "wysdmc", + 3917: "aftmux", + 3918: "pktcablemmcops", + 3919: "hyperip", + 3920: "exasoftport1", + 3921: "herodotus-net", + 3922: "sor-update", + 3923: "symb-sb-port", + 3924: "mpl-gprs-port", + 3925: "zmp", + 3926: "winport", + 3927: "natdataservice", + 3928: "netboot-pxe", + 3929: "smauth-port", + 3930: "syam-webserver", + 3931: "msr-plugin-port", + 3932: "dyn-site", + 3933: "plbserve-port", + 3934: "sunfm-port", + 3935: "sdp-portmapper", + 3936: "mailprox", + 3937: "dvbservdsc", + 3938: "dbcontrol-agent", + 3939: "aamp", + 3940: "xecp-node", + 3941: "homeportal-web", + 3942: "srdp", + 3943: "tig", + 3944: "sops", + 3945: "emcads", + 3946: "backupedge", + 3947: "ccp", + 3948: "apdap", + 3949: "drip", + 3950: "namemunge", + 3951: "pwgippfax", + 3952: "i3-sessionmgr", + 3953: "xmlink-connect", + 3954: "adrep", + 3955: "p2pcommunity", + 3956: "gvcp", + 3957: "mqe-broker", + 3958: "mqe-agent", + 3959: "treehopper", + 3960: "bess", + 3961: "proaxess", + 3962: "sbi-agent", + 3963: "thrp", + 3964: "sasggprs", + 3965: "ati-ip-to-ncpe", + 3966: "bflckmgr", + 3967: "ppsms", + 3968: "ianywhere-dbns", + 3969: "landmarks", + 3970: "lanrevagent", + 3971: "lanrevserver", + 3972: "iconp", + 3973: "progistics", + 3974: "citysearch", + 3975: "airshot", + 3976: "opswagent", + 3977: "opswmanager", + 3978: "secure-cfg-svr", + 3979: "smwan", + 3980: "acms", + 3981: "starfish", + 3982: "eis", + 3983: "eisp", + 3984: "mapper-nodemgr", + 3985: "mapper-mapethd", + 3986: "mapper-ws-ethd", + 3987: "centerline", + 3988: "dcs-config", + 3989: "bv-queryengine", + 3990: "bv-is", + 3991: "bv-smcsrv", + 3992: "bv-ds", + 3993: "bv-agent", + 3995: "iss-mgmt-ssl", + 3996: "abcsoftware", + 3997: "agentsease-db", + 3998: "dnx", + 3999: "nvcnet", + 4000: "terabase", + 4001: "newoak", + 4002: "pxc-spvr-ft", + 4003: "pxc-splr-ft", + 4004: "pxc-roid", + 4005: "pxc-pin", + 4006: "pxc-spvr", + 4007: "pxc-splr", + 4008: "netcheque", + 4009: "chimera-hwm", + 4010: "samsung-unidex", + 4011: "altserviceboot", + 4012: "pda-gate", + 4013: "acl-manager", + 4014: "taiclock", + 4015: "talarian-mcast1", + 4016: "talarian-mcast2", + 4017: "talarian-mcast3", + 4018: "talarian-mcast4", + 4019: "talarian-mcast5", + 4020: "trap", + 4021: "nexus-portal", + 4022: "dnox", + 4023: "esnm-zoning", + 4024: "tnp1-port", + 4025: "partimage", + 4026: "as-debug", + 4027: "bxp", + 4028: "dtserver-port", + 4029: "ip-qsig", + 4030: "jdmn-port", + 4031: "suucp", + 4032: "vrts-auth-port", + 4033: "sanavigator", + 4034: "ubxd", + 4035: "wap-push-http", + 4036: "wap-push-https", + 4037: "ravehd", + 4038: "fazzt-ptp", + 4039: "fazzt-admin", + 4040: "yo-main", + 4041: "houston", + 4042: "ldxp", + 4043: "nirp", + 4044: "ltp", + 4045: "npp", + 4046: "acp-proto", + 4047: "ctp-state", + 4049: "wafs", + 4050: "cisco-wafs", + 4051: "cppdp", + 4052: "interact", + 4053: "ccu-comm-1", + 4054: "ccu-comm-2", + 4055: "ccu-comm-3", + 4056: "lms", + 4057: "wfm", + 4058: "kingfisher", + 4059: "dlms-cosem", + 4060: "dsmeter-iatc", + 4061: "ice-location", + 4062: "ice-slocation", + 4063: "ice-router", + 4064: "ice-srouter", + 4065: "avanti-cdp", + 4066: "pmas", + 4067: "idp", + 4068: "ipfltbcst", + 4069: "minger", + 4070: "tripe", + 4071: "aibkup", + 4072: "zieto-sock", + 4073: "iRAPP", + 4074: "cequint-cityid", + 4075: "perimlan", + 4076: "seraph", + 4077: "ascomalarm", + 4079: "santools", + 4080: "lorica-in", + 4081: "lorica-in-sec", + 4082: "lorica-out", + 4083: "lorica-out-sec", + 4084: "fortisphere-vm", + 4086: "ftsync", + 4089: "opencore", + 4090: "omasgport", + 4091: "ewinstaller", + 4092: "ewdgs", + 4093: "pvxpluscs", + 4094: "sysrqd", + 4095: "xtgui", + 4096: "bre", + 4097: "patrolview", + 4098: "drmsfsd", + 4099: "dpcp", + 4100: "igo-incognito", + 4101: "brlp-0", + 4102: "brlp-1", + 4103: "brlp-2", + 4104: "brlp-3", + 4105: "shofar", + 4106: "synchronite", + 4107: "j-ac", + 4108: "accel", + 4109: "izm", + 4110: "g2tag", + 4111: "xgrid", + 4112: "apple-vpns-rp", + 4113: "aipn-reg", + 4114: "jomamqmonitor", + 4115: "cds", + 4116: "smartcard-tls", + 4117: "hillrserv", + 4118: "netscript", + 4119: "assuria-slm", + 4121: "e-builder", + 4122: "fprams", + 4123: "z-wave", + 4124: "tigv2", + 4125: "opsview-envoy", + 4126: "ddrepl", + 4127: "unikeypro", + 4128: "nufw", + 4129: "nuauth", + 4130: "fronet", + 4131: "stars", + 4132: "nuts-dem", + 4133: "nuts-bootp", + 4134: "nifty-hmi", + 4135: "cl-db-attach", + 4136: "cl-db-request", + 4137: "cl-db-remote", + 4138: "nettest", + 4139: "thrtx", + 4140: "cedros-fds", + 4141: "oirtgsvc", + 4142: "oidocsvc", + 4143: "oidsr", + 4145: "vvr-control", + 4146: "tgcconnect", + 4147: "vrxpservman", + 4148: "hhb-handheld", + 4149: "agslb", + 4150: "PowerAlert-nsa", + 4151: "menandmice-noh", + 4152: "idig-mux", + 4153: "mbl-battd", + 4154: "atlinks", + 4155: "bzr", + 4156: "stat-results", + 4157: "stat-scanner", + 4158: "stat-cc", + 4159: "nss", + 4160: "jini-discovery", + 4161: "omscontact", + 4162: "omstopology", + 4163: "silverpeakpeer", + 4164: "silverpeakcomm", + 4165: "altcp", + 4166: "joost", + 4167: "ddgn", + 4168: "pslicser", + 4169: "iadt-disc", + 4172: "pcoip", + 4173: "mma-discovery", + 4174: "sm-disc", + 4177: "wello", + 4178: "storman", + 4179: "MaxumSP", + 4180: "httpx", + 4181: "macbak", + 4182: "pcptcpservice", + 4183: "cyborgnet", + 4184: "universe-suite", + 4185: "wcpp", + 4188: "vatata", + 4191: "dsmipv6", + 4192: "azeti-bd", + 4197: "hctl", + 4199: "eims-admin", + 4300: "corelccam", + 4301: "d-data", + 4302: "d-data-control", + 4303: "srcp", + 4304: "owserver", + 4305: "batman", + 4306: "pinghgl", + 4307: "trueconf", + 4308: "compx-lockview", + 4309: "dserver", + 4310: "mirrtex", + 4320: "fdt-rcatp", + 4321: "rwhois", + 4322: "trim-event", + 4323: "trim-ice", + 4325: "geognosisman", + 4326: "geognosis", + 4327: "jaxer-web", + 4328: "jaxer-manager", + 4333: "ahsp", + 4340: "gaia", + 4341: "lisp-data", + 4342: "lisp-control", + 4343: "unicall", + 4344: "vinainstall", + 4345: "m4-network-as", + 4346: "elanlm", + 4347: "lansurveyor", + 4348: "itose", + 4349: "fsportmap", + 4350: "net-device", + 4351: "plcy-net-svcs", + 4352: "pjlink", + 4353: "f5-iquery", + 4354: "qsnet-trans", + 4355: "qsnet-workst", + 4356: "qsnet-assist", + 4357: "qsnet-cond", + 4358: "qsnet-nucl", + 4359: "omabcastltkm", + 4361: "nacnl", + 4362: "afore-vdp-disc", + 4366: "shadowstream", + 4368: "wxbrief", + 4369: "epmd", + 4370: "elpro-tunnel", + 4371: "l2c-disc", + 4372: "l2c-data", + 4373: "remctl", + 4375: "tolteces", + 4376: "bip", + 4377: "cp-spxsvr", + 4378: "cp-spxdpy", + 4379: "ctdb", + 4389: "xandros-cms", + 4390: "wiegand", + 4394: "apwi-disc", + 4395: "omnivisionesx", + 4400: "ds-srv", + 4401: "ds-srvr", + 4402: "ds-clnt", + 4403: "ds-user", + 4404: "ds-admin", + 4405: "ds-mail", + 4406: "ds-slp", + 4412: "smallchat", + 4413: "avi-nms-disc", + 4416: "pjj-player-disc", + 4418: "axysbridge", + 4420: "nvm-express", + 4425: "netrockey6", + 4426: "beacon-port-2", + 4430: "rsqlserver", + 4432: "l-acoustics", + 4441: "netblox", + 4442: "saris", + 4443: "pharos", + 4444: "krb524", + 4445: "upnotifyp", + 4446: "n1-fwp", + 4447: "n1-rmgmt", + 4448: "asc-slmd", + 4449: "privatewire", + 4450: "camp", + 4451: "ctisystemmsg", + 4452: "ctiprogramload", + 4453: "nssalertmgr", + 4454: "nssagentmgr", + 4455: "prchat-user", + 4456: "prchat-server", + 4457: "prRegister", + 4458: "mcp", + 4484: "hpssmgmt", + 4486: "icms", + 4488: "awacs-ice", + 4500: "ipsec-nat-t", + 4534: "armagetronad", + 4535: "ehs", + 4536: "ehs-ssl", + 4537: "wssauthsvc", + 4538: "swx-gate", + 4545: "worldscores", + 4546: "sf-lm", + 4547: "lanner-lm", + 4548: "synchromesh", + 4549: "aegate", + 4550: "gds-adppiw-db", + 4551: "ieee-mih", + 4552: "menandmice-mon", + 4554: "msfrs", + 4555: "rsip", + 4556: "dtn-bundle", + 4557: "mtcevrunqss", + 4558: "mtcevrunqman", + 4559: "hylafax", + 4566: "kwtc", + 4567: "tram", + 4568: "bmc-reporting", + 4569: "iax", + 4591: "l3t-at-an", + 4592: "hrpd-ith-at-an", + 4593: "ipt-anri-anri", + 4594: "ias-session", + 4595: "ias-paging", + 4596: "ias-neighbor", + 4597: "a21-an-1xbs", + 4598: "a16-an-an", + 4599: "a17-an-an", + 4600: "piranha1", + 4601: "piranha2", + 4621: "ventoso", + 4658: "playsta2-app", + 4659: "playsta2-lob", + 4660: "smaclmgr", + 4661: "kar2ouche", + 4662: "oms", + 4663: "noteit", + 4664: "ems", + 4665: "contclientms", + 4666: "eportcomm", + 4667: "mmacomm", + 4668: "mmaeds", + 4669: "eportcommdata", + 4670: "light", + 4671: "acter", + 4672: "rfa", + 4673: "cxws", + 4674: "appiq-mgmt", + 4675: "dhct-status", + 4676: "dhct-alerts", + 4677: "bcs", + 4678: "traversal", + 4679: "mgesupervision", + 4680: "mgemanagement", + 4681: "parliant", + 4682: "finisar", + 4683: "spike", + 4684: "rfid-rp1", + 4685: "autopac", + 4686: "msp-os", + 4687: "nst", + 4688: "mobile-p2p", + 4689: "altovacentral", + 4690: "prelude", + 4691: "mtn", + 4692: "conspiracy", + 4700: "netxms-agent", + 4701: "netxms-mgmt", + 4702: "netxms-sync", + 4711: "trinity-dist", + 4725: "truckstar", + 4726: "a26-fap-fgw", + 4727: "fcis-disc", + 4728: "capmux", + 4729: "gsmtap", + 4730: "gearman", + 4732: "ohmtrigger", + 4737: "ipdr-sp", + 4738: "solera-lpn", + 4739: "ipfix", + 4740: "ipfixs", + 4741: "lumimgrd", + 4742: "sicct-sdp", + 4743: "openhpid", + 4744: "ifsp", + 4745: "fmp", + 4746: "intelliadm-disc", + 4747: "buschtrommel", + 4749: "profilemac", + 4750: "ssad", + 4751: "spocp", + 4752: "snap", + 4753: "simon-disc", + 4754: "gre-in-udp", + 4755: "gre-udp-dtls", + 4784: "bfd-multi-ctl", + 4785: "cncp", + 4789: "vxlan", + 4790: "vxlan-gpe", + 4791: "roce", + 4800: "iims", + 4801: "iwec", + 4802: "ilss", + 4803: "notateit-disc", + 4804: "aja-ntv4-disc", + 4827: "htcp", + 4837: "varadero-0", + 4838: "varadero-1", + 4839: "varadero-2", + 4840: "opcua-udp", + 4841: "quosa", + 4842: "gw-asv", + 4843: "opcua-tls", + 4844: "gw-log", + 4845: "wcr-remlib", + 4846: "contamac-icm", + 4847: "wfc", + 4848: "appserv-http", + 4849: "appserv-https", + 4850: "sun-as-nodeagt", + 4851: "derby-repli", + 4867: "unify-debug", + 4868: "phrelay", + 4869: "phrelaydbg", + 4870: "cc-tracking", + 4871: "wired", + 4876: "tritium-can", + 4877: "lmcs", + 4878: "inst-discovery", + 4881: "socp-t", + 4882: "socp-c", + 4884: "hivestor", + 4885: "abbs", + 4894: "lyskom", + 4899: "radmin-port", + 4900: "hfcs", + 4914: "bones", + 4936: "an-signaling", + 4937: "atsc-mh-ssc", + 4940: "eq-office-4940", + 4941: "eq-office-4941", + 4942: "eq-office-4942", + 4949: "munin", + 4950: "sybasesrvmon", + 4951: "pwgwims", + 4952: "sagxtsds", + 4969: "ccss-qmm", + 4970: "ccss-qsm", + 4980: "ctxs-vpp", + 4986: "mrip", + 4987: "smar-se-port1", + 4988: "smar-se-port2", + 4989: "parallel", + 4990: "busycal", + 4991: "vrt", + 4999: "hfcs-manager", + 5000: "commplex-main", + 5001: "commplex-link", + 5002: "rfe", + 5003: "fmpro-internal", + 5004: "avt-profile-1", + 5005: "avt-profile-2", + 5006: "wsm-server", + 5007: "wsm-server-ssl", + 5008: "synapsis-edge", + 5009: "winfs", + 5010: "telelpathstart", + 5011: "telelpathattack", + 5012: "nsp", + 5013: "fmpro-v6", + 5014: "onpsocket", + 5020: "zenginkyo-1", + 5021: "zenginkyo-2", + 5022: "mice", + 5023: "htuilsrv", + 5024: "scpi-telnet", + 5025: "scpi-raw", + 5026: "strexec-d", + 5027: "strexec-s", + 5029: "infobright", + 5030: "surfpass", + 5031: "dmp", + 5042: "asnaacceler8db", + 5043: "swxadmin", + 5044: "lxi-evntsvc", + 5046: "vpm-udp", + 5047: "iscape", + 5049: "ivocalize", + 5050: "mmcc", + 5051: "ita-agent", + 5052: "ita-manager", + 5053: "rlm-disc", + 5055: "unot", + 5056: "intecom-ps1", + 5057: "intecom-ps2", + 5058: "locus-disc", + 5059: "sds", + 5060: "sip", + 5061: "sips", + 5062: "na-localise", + 5064: "ca-1", + 5065: "ca-2", + 5066: "stanag-5066", + 5067: "authentx", + 5069: "i-net-2000-npr", + 5070: "vtsas", + 5071: "powerschool", + 5072: "ayiya", + 5073: "tag-pm", + 5074: "alesquery", + 5078: "pixelpusher", + 5079: "cp-spxrpts", + 5080: "onscreen", + 5081: "sdl-ets", + 5082: "qcp", + 5083: "qfp", + 5084: "llrp", + 5085: "encrypted-llrp", + 5092: "magpie", + 5093: "sentinel-lm", + 5094: "hart-ip", + 5099: "sentlm-srv2srv", + 5100: "socalia", + 5101: "talarian-udp", + 5102: "oms-nonsecure", + 5104: "tinymessage", + 5105: "hughes-ap", + 5111: "taep-as-svc", + 5112: "pm-cmdsvr", + 5116: "emb-proj-cmd", + 5120: "barracuda-bbs", + 5133: "nbt-pc", + 5136: "minotaur-sa", + 5137: "ctsd", + 5145: "rmonitor-secure", + 5150: "atmp", + 5151: "esri-sde", + 5152: "sde-discovery", + 5154: "bzflag", + 5155: "asctrl-agent", + 5164: "vpa-disc", + 5165: "ife-icorp", + 5166: "winpcs", + 5167: "scte104", + 5168: "scte30", + 5190: "aol", + 5191: "aol-1", + 5192: "aol-2", + 5193: "aol-3", + 5200: "targus-getdata", + 5201: "targus-getdata1", + 5202: "targus-getdata2", + 5203: "targus-getdata3", + 5223: "hpvirtgrp", + 5224: "hpvirtctrl", + 5225: "hp-server", + 5226: "hp-status", + 5227: "perfd", + 5234: "eenet", + 5235: "galaxy-network", + 5236: "padl2sim", + 5237: "mnet-discovery", + 5245: "downtools-disc", + 5246: "capwap-control", + 5247: "capwap-data", + 5248: "caacws", + 5249: "caaclang2", + 5250: "soagateway", + 5251: "caevms", + 5252: "movaz-ssc", + 5264: "3com-njack-1", + 5265: "3com-njack-2", + 5270: "cartographerxmp", + 5271: "cuelink-disc", + 5272: "pk", + 5282: "transmit-port", + 5298: "presence", + 5299: "nlg-data", + 5300: "hacl-hb", + 5301: "hacl-gs", + 5302: "hacl-cfg", + 5303: "hacl-probe", + 5304: "hacl-local", + 5305: "hacl-test", + 5306: "sun-mc-grp", + 5307: "sco-aip", + 5308: "cfengine", + 5309: "jprinter", + 5310: "outlaws", + 5312: "permabit-cs", + 5313: "rrdp", + 5314: "opalis-rbt-ipc", + 5315: "hacl-poll", + 5343: "kfserver", + 5344: "xkotodrcp", + 5349: "stuns", + 5350: "pcp-multicast", + 5351: "pcp", + 5352: "dns-llq", + 5353: "mdns", + 5354: "mdnsresponder", + 5355: "llmnr", + 5356: "ms-smlbiz", + 5357: "wsdapi", + 5358: "wsdapi-s", + 5359: "ms-alerter", + 5360: "ms-sideshow", + 5361: "ms-s-sideshow", + 5362: "serverwsd2", + 5363: "net-projection", + 5364: "kdnet", + 5397: "stresstester", + 5398: "elektron-admin", + 5399: "securitychase", + 5400: "excerpt", + 5401: "excerpts", + 5402: "mftp", + 5403: "hpoms-ci-lstn", + 5404: "hpoms-dps-lstn", + 5405: "netsupport", + 5406: "systemics-sox", + 5407: "foresyte-clear", + 5408: "foresyte-sec", + 5409: "salient-dtasrv", + 5410: "salient-usrmgr", + 5411: "actnet", + 5412: "continuus", + 5413: "wwiotalk", + 5414: "statusd", + 5415: "ns-server", + 5416: "sns-gateway", + 5417: "sns-agent", + 5418: "mcntp", + 5419: "dj-ice", + 5420: "cylink-c", + 5421: "netsupport2", + 5422: "salient-mux", + 5423: "virtualuser", + 5424: "beyond-remote", + 5425: "br-channel", + 5426: "devbasic", + 5427: "sco-peer-tta", + 5428: "telaconsole", + 5429: "base", + 5430: "radec-corp", + 5431: "park-agent", + 5432: "postgresql", + 5433: "pyrrho", + 5434: "sgi-arrayd", + 5435: "sceanics", + 5436: "pmip6-cntl", + 5437: "pmip6-data", + 5443: "spss", + 5450: "tiepie-disc", + 5453: "surebox", + 5454: "apc-5454", + 5455: "apc-5455", + 5456: "apc-5456", + 5461: "silkmeter", + 5462: "ttl-publisher", + 5463: "ttlpriceproxy", + 5464: "quailnet", + 5465: "netops-broker", + 5474: "apsolab-rpc", + 5500: "fcp-addr-srvr1", + 5501: "fcp-addr-srvr2", + 5502: "fcp-srvr-inst1", + 5503: "fcp-srvr-inst2", + 5504: "fcp-cics-gw1", + 5505: "checkoutdb", + 5506: "amc", + 5553: "sgi-eventmond", + 5554: "sgi-esphttp", + 5555: "personal-agent", + 5556: "freeciv", + 5567: "dof-dps-mc-sec", + 5568: "sdt", + 5569: "rdmnet-device", + 5573: "sdmmp", + 5580: "tmosms0", + 5581: "tmosms1", + 5582: "fac-restore", + 5583: "tmo-icon-sync", + 5584: "bis-web", + 5585: "bis-sync", + 5597: "ininmessaging", + 5598: "mctfeed", + 5599: "esinstall", + 5600: "esmmanager", + 5601: "esmagent", + 5602: "a1-msc", + 5603: "a1-bs", + 5604: "a3-sdunode", + 5605: "a4-sdunode", + 5627: "ninaf", + 5628: "htrust", + 5629: "symantec-sfdb", + 5630: "precise-comm", + 5631: "pcanywheredata", + 5632: "pcanywherestat", + 5633: "beorl", + 5634: "xprtld", + 5670: "zre-disc", + 5671: "amqps", + 5672: "amqp", + 5673: "jms", + 5674: "hyperscsi-port", + 5675: "v5ua", + 5676: "raadmin", + 5677: "questdb2-lnchr", + 5678: "rrac", + 5679: "dccm", + 5680: "auriga-router", + 5681: "ncxcp", + 5682: "brightcore", + 5683: "coap", + 5684: "coaps", + 5687: "gog-multiplayer", + 5688: "ggz", + 5689: "qmvideo", + 5713: "proshareaudio", + 5714: "prosharevideo", + 5715: "prosharedata", + 5716: "prosharerequest", + 5717: "prosharenotify", + 5718: "dpm", + 5719: "dpm-agent", + 5720: "ms-licensing", + 5721: "dtpt", + 5722: "msdfsr", + 5723: "omhs", + 5724: "omsdk", + 5728: "io-dist-group", + 5729: "openmail", + 5730: "unieng", + 5741: "ida-discover1", + 5742: "ida-discover2", + 5743: "watchdoc-pod", + 5744: "watchdoc", + 5745: "fcopy-server", + 5746: "fcopys-server", + 5747: "tunatic", + 5748: "tunalyzer", + 5750: "rscd", + 5755: "openmailg", + 5757: "x500ms", + 5766: "openmailns", + 5767: "s-openmail", + 5768: "openmailpxy", + 5769: "spramsca", + 5770: "spramsd", + 5771: "netagent", + 5777: "dali-port", + 5781: "3par-evts", + 5782: "3par-mgmt", + 5783: "3par-mgmt-ssl", + 5784: "ibar", + 5785: "3par-rcopy", + 5786: "cisco-redu", + 5787: "waascluster", + 5793: "xtreamx", + 5794: "spdp", + 5813: "icmpd", + 5814: "spt-automation", + 5859: "wherehoo", + 5863: "ppsuitemsg", + 5900: "rfb", + 5910: "cm", + 5911: "cpdlc", + 5912: "fis", + 5913: "ads-c", + 5963: "indy", + 5968: "mppolicy-v5", + 5969: "mppolicy-mgr", + 5984: "couchdb", + 5985: "wsman", + 5986: "wsmans", + 5987: "wbem-rmi", + 5988: "wbem-http", + 5989: "wbem-https", + 5990: "wbem-exp-https", + 5991: "nuxsl", + 5992: "consul-insight", + 5999: "cvsup", + 6064: "ndl-ahp-svc", + 6065: "winpharaoh", + 6066: "ewctsp", + 6069: "trip", + 6070: "messageasap", + 6071: "ssdtp", + 6072: "diagnose-proc", + 6073: "directplay8", + 6074: "max", + 6080: "gue", + 6081: "geneve", + 6082: "p25cai", + 6083: "miami-bcast", + 6085: "konspire2b", + 6086: "pdtp", + 6087: "ldss", + 6088: "doglms-notify", + 6100: "synchronet-db", + 6101: "synchronet-rtc", + 6102: "synchronet-upd", + 6103: "rets", + 6104: "dbdb", + 6105: "primaserver", + 6106: "mpsserver", + 6107: "etc-control", + 6108: "sercomm-scadmin", + 6109: "globecast-id", + 6110: "softcm", + 6111: "spc", + 6112: "dtspcd", + 6118: "tipc", + 6122: "bex-webadmin", + 6123: "backup-express", + 6124: "pnbs", + 6133: "nbt-wol", + 6140: "pulsonixnls", + 6141: "meta-corp", + 6142: "aspentec-lm", + 6143: "watershed-lm", + 6144: "statsci1-lm", + 6145: "statsci2-lm", + 6146: "lonewolf-lm", + 6147: "montage-lm", + 6148: "ricardo-lm", + 6149: "tal-pod", + 6160: "ecmp-data", + 6161: "patrol-ism", + 6162: "patrol-coll", + 6163: "pscribe", + 6200: "lm-x", + 6201: "thermo-calc", + 6209: "qmtps", + 6222: "radmind", + 6241: "jeol-nsddp-1", + 6242: "jeol-nsddp-2", + 6243: "jeol-nsddp-3", + 6244: "jeol-nsddp-4", + 6251: "tl1-raw-ssl", + 6252: "tl1-ssh", + 6253: "crip", + 6268: "grid", + 6269: "grid-alt", + 6300: "bmc-grx", + 6301: "bmc-ctd-ldap", + 6306: "ufmp", + 6315: "scup-disc", + 6316: "abb-escp", + 6317: "nav-data", + 6320: "repsvc", + 6321: "emp-server1", + 6322: "emp-server2", + 6324: "hrd-ns-disc", + 6343: "sflow", + 6346: "gnutella-svc", + 6347: "gnutella-rtr", + 6350: "adap", + 6355: "pmcs", + 6360: "metaedit-mu", + 6363: "ndn", + 6370: "metaedit-se", + 6382: "metatude-mds", + 6389: "clariion-evr01", + 6390: "metaedit-ws", + 6417: "faxcomservice", + 6419: "svdrp-disc", + 6420: "nim-vdrshell", + 6421: "nim-wan", + 6443: "sun-sr-https", + 6444: "sge-qmaster", + 6445: "sge-execd", + 6446: "mysql-proxy", + 6455: "skip-cert-recv", + 6456: "skip-cert-send", + 6464: "ieee11073-20701", + 6471: "lvision-lm", + 6480: "sun-sr-http", + 6481: "servicetags", + 6482: "ldoms-mgmt", + 6483: "SunVTS-RMI", + 6484: "sun-sr-jms", + 6485: "sun-sr-iiop", + 6486: "sun-sr-iiops", + 6487: "sun-sr-iiop-aut", + 6488: "sun-sr-jmx", + 6489: "sun-sr-admin", + 6500: "boks", + 6501: "boks-servc", + 6502: "boks-servm", + 6503: "boks-clntd", + 6505: "badm-priv", + 6506: "badm-pub", + 6507: "bdir-priv", + 6508: "bdir-pub", + 6509: "mgcs-mfp-port", + 6510: "mcer-port", + 6511: "dccp-udp", + 6514: "syslog-tls", + 6515: "elipse-rec", + 6543: "lds-distrib", + 6544: "lds-dump", + 6547: "apc-6547", + 6548: "apc-6548", + 6549: "apc-6549", + 6550: "fg-sysupdate", + 6551: "sum", + 6558: "xdsxdm", + 6566: "sane-port", + 6568: "rp-reputation", + 6579: "affiliate", + 6580: "parsec-master", + 6581: "parsec-peer", + 6582: "parsec-game", + 6583: "joaJewelSuite", + 6619: "odette-ftps", + 6620: "kftp-data", + 6621: "kftp", + 6622: "mcftp", + 6623: "ktelnet", + 6626: "wago-service", + 6627: "nexgen", + 6628: "afesc-mc", + 6629: "nexgen-aux", + 6633: "cisco-vpath-tun", + 6634: "mpls-pm", + 6635: "mpls-udp", + 6636: "mpls-udp-dtls", + 6653: "openflow", + 6657: "palcom-disc", + 6670: "vocaltec-gold", + 6671: "p4p-portal", + 6672: "vision-server", + 6673: "vision-elmd", + 6678: "vfbp-disc", + 6679: "osaut", + 6689: "tsa", + 6696: "babel", + 6701: "kti-icad-srvr", + 6702: "e-design-net", + 6703: "e-design-web", + 6714: "ibprotocol", + 6715: "fibotrader-com", + 6767: "bmc-perf-agent", + 6768: "bmc-perf-mgrd", + 6769: "adi-gxp-srvprt", + 6770: "plysrv-http", + 6771: "plysrv-https", + 6784: "bfd-lag", + 6785: "dgpf-exchg", + 6786: "smc-jmx", + 6787: "smc-admin", + 6788: "smc-http", + 6790: "hnmp", + 6791: "hnm", + 6801: "acnet", + 6831: "ambit-lm", + 6841: "netmo-default", + 6842: "netmo-http", + 6850: "iccrushmore", + 6868: "acctopus-st", + 6888: "muse", + 6935: "ethoscan", + 6936: "xsmsvc", + 6946: "bioserver", + 6951: "otlp", + 6961: "jmact3", + 6962: "jmevt2", + 6963: "swismgr1", + 6964: "swismgr2", + 6965: "swistrap", + 6966: "swispol", + 6969: "acmsoda", + 6997: "MobilitySrv", + 6998: "iatp-highpri", + 6999: "iatp-normalpri", + 7000: "afs3-fileserver", + 7001: "afs3-callback", + 7002: "afs3-prserver", + 7003: "afs3-vlserver", + 7004: "afs3-kaserver", + 7005: "afs3-volser", + 7006: "afs3-errors", + 7007: "afs3-bos", + 7008: "afs3-update", + 7009: "afs3-rmtsys", + 7010: "ups-onlinet", + 7011: "talon-disc", + 7012: "talon-engine", + 7013: "microtalon-dis", + 7014: "microtalon-com", + 7015: "talon-webserver", + 7016: "spg", + 7017: "grasp", + 7019: "doceri-view", + 7020: "dpserve", + 7021: "dpserveadmin", + 7022: "ctdp", + 7023: "ct2nmcs", + 7024: "vmsvc", + 7025: "vmsvc-2", + 7030: "op-probe", + 7040: "quest-disc", + 7070: "arcp", + 7071: "iwg1", + 7080: "empowerid", + 7088: "zixi-transport", + 7095: "jdp-disc", + 7099: "lazy-ptop", + 7100: "font-service", + 7101: "elcn", + 7107: "aes-x170", + 7121: "virprot-lm", + 7128: "scenidm", + 7129: "scenccs", + 7161: "cabsm-comm", + 7162: "caistoragemgr", + 7163: "cacsambroker", + 7164: "fsr", + 7165: "doc-server", + 7166: "aruba-server", + 7169: "ccag-pib", + 7170: "nsrp", + 7171: "drm-production", + 7174: "clutild", + 7181: "janus-disc", + 7200: "fodms", + 7201: "dlip", + 7227: "ramp", + 7235: "aspcoordination", + 7244: "frc-hicp-disc", + 7262: "cnap", + 7272: "watchme-7272", + 7273: "oma-rlp", + 7274: "oma-rlp-s", + 7275: "oma-ulp", + 7276: "oma-ilp", + 7277: "oma-ilp-s", + 7278: "oma-dcdocbs", + 7279: "ctxlic", + 7280: "itactionserver1", + 7281: "itactionserver2", + 7282: "mzca-alert", + 7365: "lcm-server", + 7391: "mindfilesys", + 7392: "mrssrendezvous", + 7393: "nfoldman", + 7394: "fse", + 7395: "winqedit", + 7397: "hexarc", + 7400: "rtps-discovery", + 7401: "rtps-dd-ut", + 7402: "rtps-dd-mt", + 7410: "ionixnetmon", + 7411: "daqstream", + 7421: "mtportmon", + 7426: "pmdmgr", + 7427: "oveadmgr", + 7428: "ovladmgr", + 7429: "opi-sock", + 7430: "xmpv7", + 7431: "pmd", + 7437: "faximum", + 7443: "oracleas-https", + 7473: "rise", + 7491: "telops-lmd", + 7500: "silhouette", + 7501: "ovbus", + 7510: "ovhpas", + 7511: "pafec-lm", + 7542: "saratoga", + 7543: "atul", + 7544: "nta-ds", + 7545: "nta-us", + 7546: "cfs", + 7547: "cwmp", + 7548: "tidp", + 7549: "nls-tl", + 7550: "cloudsignaling", + 7560: "sncp", + 7566: "vsi-omega", + 7570: "aries-kfinder", + 7574: "coherence-disc", + 7588: "sun-lm", + 7606: "mipi-debug", + 7624: "indi", + 7627: "soap-http", + 7628: "zen-pawn", + 7629: "xdas", + 7633: "pmdfmgt", + 7648: "cuseeme", + 7674: "imqtunnels", + 7675: "imqtunnel", + 7676: "imqbrokerd", + 7677: "sun-user-https", + 7680: "pando-pub", + 7689: "collaber", + 7697: "klio", + 7707: "sync-em7", + 7708: "scinet", + 7720: "medimageportal", + 7724: "nsdeepfreezectl", + 7725: "nitrogen", + 7726: "freezexservice", + 7727: "trident-data", + 7728: "osvr", + 7734: "smip", + 7738: "aiagent", + 7741: "scriptview", + 7743: "sstp-1", + 7744: "raqmon-pdu", + 7747: "prgp", + 7777: "cbt", + 7778: "interwise", + 7779: "vstat", + 7781: "accu-lmgr", + 7784: "s-bfd", + 7786: "minivend", + 7787: "popup-reminders", + 7789: "office-tools", + 7794: "q3ade", + 7797: "pnet-conn", + 7798: "pnet-enc", + 7799: "altbsdp", + 7800: "asr", + 7801: "ssp-client", + 7802: "vns-tp", + 7810: "rbt-wanopt", + 7845: "apc-7845", + 7846: "apc-7846", + 7872: "mipv6tls", + 7880: "pss", + 7887: "ubroker", + 7900: "mevent", + 7901: "tnos-sp", + 7902: "tnos-dp", + 7903: "tnos-dps", + 7913: "qo-secure", + 7932: "t2-drm", + 7933: "t2-brm", + 7962: "generalsync", + 7967: "supercell", + 7979: "micromuse-ncps", + 7980: "quest-vista", + 7982: "sossd-disc", + 7998: "usicontentpush", + 7999: "irdmi2", + 8000: "irdmi", + 8001: "vcom-tunnel", + 8002: "teradataordbms", + 8003: "mcreport", + 8005: "mxi", + 8006: "wpl-disc", + 8007: "warppipe", + 8008: "http-alt", + 8019: "qbdb", + 8020: "intu-ec-svcdisc", + 8021: "intu-ec-client", + 8022: "oa-system", + 8025: "ca-audit-da", + 8026: "ca-audit-ds", + 8032: "pro-ed", + 8033: "mindprint", + 8034: "vantronix-mgmt", + 8040: "ampify", + 8041: "enguity-xccetp", + 8052: "senomix01", + 8053: "senomix02", + 8054: "senomix03", + 8055: "senomix04", + 8056: "senomix05", + 8057: "senomix06", + 8058: "senomix07", + 8059: "senomix08", + 8060: "aero", + 8074: "gadugadu", + 8080: "http-alt", + 8081: "sunproxyadmin", + 8082: "us-cli", + 8083: "us-srv", + 8086: "d-s-n", + 8087: "simplifymedia", + 8088: "radan-http", + 8097: "sac", + 8100: "xprint-server", + 8115: "mtl8000-matrix", + 8116: "cp-cluster", + 8118: "privoxy", + 8121: "apollo-data", + 8122: "apollo-admin", + 8128: "paycash-online", + 8129: "paycash-wbp", + 8130: "indigo-vrmi", + 8131: "indigo-vbcp", + 8132: "dbabble", + 8148: "isdd", + 8149: "eor-game", + 8160: "patrol", + 8161: "patrol-snmp", + 8182: "vmware-fdm", + 8184: "itach", + 8192: "spytechphone", + 8194: "blp1", + 8195: "blp2", + 8199: "vvr-data", + 8200: "trivnet1", + 8201: "trivnet2", + 8202: "aesop", + 8204: "lm-perfworks", + 8205: "lm-instmgr", + 8206: "lm-dta", + 8207: "lm-sserver", + 8208: "lm-webwatcher", + 8230: "rexecj", + 8231: "hncp-udp-port", + 8232: "hncp-dtls-port", + 8243: "synapse-nhttps", + 8276: "pando-sec", + 8280: "synapse-nhttp", + 8282: "libelle-disc", + 8292: "blp3", + 8294: "blp4", + 8300: "tmi", + 8301: "amberon", + 8320: "tnp-discover", + 8321: "tnp", + 8322: "garmin-marine", + 8351: "server-find", + 8376: "cruise-enum", + 8377: "cruise-swroute", + 8378: "cruise-config", + 8379: "cruise-diags", + 8380: "cruise-update", + 8383: "m2mservices", + 8384: "marathontp", + 8400: "cvd", + 8401: "sabarsd", + 8402: "abarsd", + 8403: "admind", + 8416: "espeech", + 8417: "espeech-rtp", + 8442: "cybro-a-bus", + 8443: "pcsync-https", + 8444: "pcsync-http", + 8445: "copy-disc", + 8450: "npmp", + 8472: "otv", + 8473: "vp2p", + 8474: "noteshare", + 8500: "fmtp", + 8501: "cmtp-av", + 8503: "lsp-self-ping", + 8554: "rtsp-alt", + 8555: "d-fence", + 8567: "dof-tunnel", + 8600: "asterix", + 8609: "canon-cpp-disc", + 8610: "canon-mfnp", + 8611: "canon-bjnp1", + 8612: "canon-bjnp2", + 8613: "canon-bjnp3", + 8614: "canon-bjnp4", + 8675: "msi-cps-rm-disc", + 8686: "sun-as-jmxrmi", + 8732: "dtp-net", + 8733: "ibus", + 8763: "mc-appserver", + 8764: "openqueue", + 8765: "ultraseek-http", + 8766: "amcs", + 8770: "dpap", + 8786: "msgclnt", + 8787: "msgsrvr", + 8793: "acd-pm", + 8800: "sunwebadmin", + 8804: "truecm", + 8805: "pfcp", + 8808: "ssports-bcast", + 8873: "dxspider", + 8880: "cddbp-alt", + 8883: "secure-mqtt", + 8888: "ddi-udp-1", + 8889: "ddi-udp-2", + 8890: "ddi-udp-3", + 8891: "ddi-udp-4", + 8892: "ddi-udp-5", + 8893: "ddi-udp-6", + 8894: "ddi-udp-7", + 8899: "ospf-lite", + 8900: "jmb-cds1", + 8901: "jmb-cds2", + 8910: "manyone-http", + 8911: "manyone-xml", + 8912: "wcbackup", + 8913: "dragonfly", + 8954: "cumulus-admin", + 8980: "nod-provider", + 8981: "nod-client", + 8989: "sunwebadmins", + 8990: "http-wmap", + 8991: "https-wmap", + 8999: "bctp", + 9000: "cslistener", + 9001: "etlservicemgr", + 9002: "dynamid", + 9007: "ogs-client", + 9009: "pichat", + 9020: "tambora", + 9021: "panagolin-ident", + 9022: "paragent", + 9023: "swa-1", + 9024: "swa-2", + 9025: "swa-3", + 9026: "swa-4", + 9060: "CardWeb-RT", + 9080: "glrpc", + 9084: "aurora", + 9085: "ibm-rsyscon", + 9086: "net2display", + 9087: "classic", + 9088: "sqlexec", + 9089: "sqlexec-ssl", + 9090: "websm", + 9091: "xmltec-xmlmail", + 9092: "XmlIpcRegSvc", + 9100: "hp-pdl-datastr", + 9101: "bacula-dir", + 9102: "bacula-fd", + 9103: "bacula-sd", + 9104: "peerwire", + 9105: "xadmin", + 9106: "astergate-disc", + 9119: "mxit", + 9131: "dddp", + 9160: "apani1", + 9161: "apani2", + 9162: "apani3", + 9163: "apani4", + 9164: "apani5", + 9191: "sun-as-jpda", + 9200: "wap-wsp", + 9201: "wap-wsp-wtp", + 9202: "wap-wsp-s", + 9203: "wap-wsp-wtp-s", + 9204: "wap-vcard", + 9205: "wap-vcal", + 9206: "wap-vcard-s", + 9207: "wap-vcal-s", + 9208: "rjcdb-vcards", + 9209: "almobile-system", + 9210: "oma-mlp", + 9211: "oma-mlp-s", + 9212: "serverviewdbms", + 9213: "serverstart", + 9214: "ipdcesgbs", + 9215: "insis", + 9216: "acme", + 9217: "fsc-port", + 9222: "teamcoherence", + 9255: "mon", + 9277: "traingpsdata", + 9278: "pegasus", + 9279: "pegasus-ctl", + 9280: "pgps", + 9281: "swtp-port1", + 9282: "swtp-port2", + 9283: "callwaveiam", + 9284: "visd", + 9285: "n2h2server", + 9286: "n2receive", + 9287: "cumulus", + 9292: "armtechdaemon", + 9293: "storview", + 9294: "armcenterhttp", + 9295: "armcenterhttps", + 9300: "vrace", + 9318: "secure-ts", + 9321: "guibase", + 9343: "mpidcmgr", + 9344: "mphlpdmc", + 9346: "ctechlicensing", + 9374: "fjdmimgr", + 9380: "boxp", + 9396: "fjinvmgr", + 9397: "mpidcagt", + 9400: "sec-t4net-srv", + 9401: "sec-t4net-clt", + 9402: "sec-pc2fax-srv", + 9418: "git", + 9443: "tungsten-https", + 9444: "wso2esb-console", + 9450: "sntlkeyssrvr", + 9500: "ismserver", + 9522: "sma-spw", + 9535: "mngsuite", + 9536: "laes-bf", + 9555: "trispen-sra", + 9592: "ldgateway", + 9593: "cba8", + 9594: "msgsys", + 9595: "pds", + 9596: "mercury-disc", + 9597: "pd-admin", + 9598: "vscp", + 9599: "robix", + 9600: "micromuse-ncpw", + 9612: "streamcomm-ds", + 9618: "condor", + 9628: "odbcpathway", + 9629: "uniport", + 9632: "mc-comm", + 9667: "xmms2", + 9668: "tec5-sdctp", + 9694: "client-wakeup", + 9695: "ccnx", + 9700: "board-roar", + 9747: "l5nas-parchan", + 9750: "board-voip", + 9753: "rasadv", + 9762: "tungsten-http", + 9800: "davsrc", + 9801: "sstp-2", + 9802: "davsrcs", + 9875: "sapv1", + 9878: "kca-service", + 9888: "cyborg-systems", + 9889: "gt-proxy", + 9898: "monkeycom", + 9899: "sctp-tunneling", + 9900: "iua", + 9901: "enrp", + 9903: "multicast-ping", + 9909: "domaintime", + 9911: "sype-transport", + 9950: "apc-9950", + 9951: "apc-9951", + 9952: "apc-9952", + 9953: "acis", + 9955: "alljoyn-mcm", + 9956: "alljoyn", + 9966: "odnsp", + 9987: "dsm-scm-target", + 9990: "osm-appsrvr", + 9991: "osm-oev", + 9992: "palace-1", + 9993: "palace-2", + 9994: "palace-3", + 9995: "palace-4", + 9996: "palace-5", + 9997: "palace-6", + 9998: "distinct32", + 9999: "distinct", + 10000: "ndmp", + 10001: "scp-config", + 10002: "documentum", + 10003: "documentum-s", + 10007: "mvs-capacity", + 10008: "octopus", + 10009: "swdtp-sv", + 10050: "zabbix-agent", + 10051: "zabbix-trapper", + 10080: "amanda", + 10081: "famdc", + 10100: "itap-ddtp", + 10101: "ezmeeting-2", + 10102: "ezproxy-2", + 10103: "ezrelay", + 10104: "swdtp", + 10107: "bctp-server", + 10110: "nmea-0183", + 10111: "nmea-onenet", + 10113: "netiq-endpoint", + 10114: "netiq-qcheck", + 10115: "netiq-endpt", + 10116: "netiq-voipa", + 10117: "iqrm", + 10128: "bmc-perf-sd", + 10160: "qb-db-server", + 10161: "snmpdtls", + 10162: "snmpdtls-trap", + 10200: "trisoap", + 10201: "rscs", + 10252: "apollo-relay", + 10253: "eapol-relay", + 10260: "axis-wimp-port", + 10288: "blocks", + 10439: "bngsync", + 10500: "hip-nat-t", + 10540: "MOS-lower", + 10541: "MOS-upper", + 10542: "MOS-aux", + 10543: "MOS-soap", + 10544: "MOS-soap-opt", + 10800: "gap", + 10805: "lpdg", + 10810: "nmc-disc", + 10860: "helix", + 10880: "bveapi", + 10990: "rmiaux", + 11000: "irisa", + 11001: "metasys", + 10023: "cefd-vmp", + 11095: "weave", + 11106: "sgi-lk", + 11108: "myq-termlink", + 11111: "vce", + 11112: "dicom", + 11161: "suncacao-snmp", + 11162: "suncacao-jmxmp", + 11163: "suncacao-rmi", + 11164: "suncacao-csa", + 11165: "suncacao-websvc", + 11171: "snss", + 11201: "smsqp", + 11208: "wifree", + 11211: "memcache", + 11319: "imip", + 11320: "imip-channels", + 11321: "arena-server", + 11367: "atm-uhas", + 11371: "hkp", + 11430: "lsdp", + 11600: "tempest-port", + 11720: "h323callsigalt", + 11723: "emc-xsw-dcache", + 11751: "intrepid-ssl", + 11796: "lanschool-mpt", + 11876: "xoraya", + 11877: "x2e-disc", + 11967: "sysinfo-sp", + 12000: "entextxid", + 12001: "entextnetwk", + 12002: "entexthigh", + 12003: "entextmed", + 12004: "entextlow", + 12005: "dbisamserver1", + 12006: "dbisamserver2", + 12007: "accuracer", + 12008: "accuracer-dbms", + 12009: "ghvpn", + 12012: "vipera", + 12013: "vipera-ssl", + 12109: "rets-ssl", + 12121: "nupaper-ss", + 12168: "cawas", + 12172: "hivep", + 12300: "linogridengine", + 12321: "warehouse-sss", + 12322: "warehouse", + 12345: "italk", + 12753: "tsaf", + 13160: "i-zipqd", + 13216: "bcslogc", + 13217: "rs-pias", + 13218: "emc-vcas-udp", + 13223: "powwow-client", + 13224: "powwow-server", + 13400: "doip-disc", + 13720: "bprd", + 13721: "bpdbm", + 13722: "bpjava-msvc", + 13724: "vnetd", + 13782: "bpcd", + 13783: "vopied", + 13785: "nbdb", + 13786: "nomdb", + 13818: "dsmcc-config", + 13819: "dsmcc-session", + 13820: "dsmcc-passthru", + 13821: "dsmcc-download", + 13822: "dsmcc-ccp", + 13894: "ucontrol", + 13929: "dta-systems", + 14000: "scotty-ft", + 14001: "sua", + 14002: "scotty-disc", + 14033: "sage-best-com1", + 14034: "sage-best-com2", + 14141: "vcs-app", + 14142: "icpp", + 14145: "gcm-app", + 14149: "vrts-tdd", + 14154: "vad", + 14250: "cps", + 14414: "ca-web-update", + 14936: "hde-lcesrvr-1", + 14937: "hde-lcesrvr-2", + 15000: "hydap", + 15118: "v2g-secc", + 15345: "xpilot", + 15363: "3link", + 15555: "cisco-snat", + 15660: "bex-xr", + 15740: "ptp", + 15998: "2ping", + 16003: "alfin", + 16161: "sun-sea-port", + 16309: "etb4j", + 16310: "pduncs", + 16311: "pdefmns", + 16360: "netserialext1", + 16361: "netserialext2", + 16367: "netserialext3", + 16368: "netserialext4", + 16384: "connected", + 16666: "vtp", + 16900: "newbay-snc-mc", + 16950: "sgcip", + 16991: "intel-rci-mp", + 16992: "amt-soap-http", + 16993: "amt-soap-https", + 16994: "amt-redir-tcp", + 16995: "amt-redir-tls", + 17007: "isode-dua", + 17185: "soundsvirtual", + 17219: "chipper", + 17220: "avtp", + 17221: "avdecc", + 17222: "cpsp", + 17224: "trdp-pd", + 17225: "trdp-md", + 17234: "integrius-stp", + 17235: "ssh-mgmt", + 17500: "db-lsp-disc", + 17729: "ea", + 17754: "zep", + 17755: "zigbee-ip", + 17756: "zigbee-ips", + 18000: "biimenu", + 18181: "opsec-cvp", + 18182: "opsec-ufp", + 18183: "opsec-sam", + 18184: "opsec-lea", + 18185: "opsec-omi", + 18186: "ohsc", + 18187: "opsec-ela", + 18241: "checkpoint-rtm", + 18262: "gv-pf", + 18463: "ac-cluster", + 18634: "rds-ib", + 18635: "rds-ip", + 18668: "vdmmesh-disc", + 18769: "ique", + 18881: "infotos", + 18888: "apc-necmp", + 19000: "igrid", + 19007: "scintilla", + 19191: "opsec-uaa", + 19194: "ua-secureagent", + 19220: "cora-disc", + 19283: "keysrvr", + 19315: "keyshadow", + 19398: "mtrgtrans", + 19410: "hp-sco", + 19411: "hp-sca", + 19412: "hp-sessmon", + 19539: "fxuptp", + 19540: "sxuptp", + 19541: "jcp", + 19788: "mle", + 19999: "dnp-sec", + 20000: "dnp", + 20001: "microsan", + 20002: "commtact-http", + 20003: "commtact-https", + 20005: "openwebnet", + 20012: "ss-idi-disc", + 20014: "opendeploy", + 20034: "nburn-id", + 20046: "tmophl7mts", + 20048: "mountd", + 20049: "nfsrdma", + 20167: "tolfab", + 20202: "ipdtp-port", + 20222: "ipulse-ics", + 20480: "emwavemsg", + 20670: "track", + 20999: "athand-mmp", + 21000: "irtrans", + 21554: "dfserver", + 21590: "vofr-gateway", + 21800: "tvpm", + 21845: "webphone", + 21846: "netspeak-is", + 21847: "netspeak-cs", + 21848: "netspeak-acd", + 21849: "netspeak-cps", + 22000: "snapenetio", + 22001: "optocontrol", + 22002: "optohost002", + 22003: "optohost003", + 22004: "optohost004", + 22005: "optohost004", + 22273: "wnn6", + 22305: "cis", + 22335: "shrewd-stream", + 22343: "cis-secure", + 22347: "wibukey", + 22350: "codemeter", + 22555: "vocaltec-phone", + 22763: "talikaserver", + 22800: "aws-brf", + 22951: "brf-gw", + 23000: "inovaport1", + 23001: "inovaport2", + 23002: "inovaport3", + 23003: "inovaport4", + 23004: "inovaport5", + 23005: "inovaport6", + 23272: "s102", + 23294: "5afe-disc", + 23333: "elxmgmt", + 23400: "novar-dbase", + 23401: "novar-alarm", + 23402: "novar-global", + 24000: "med-ltp", + 24001: "med-fsp-rx", + 24002: "med-fsp-tx", + 24003: "med-supp", + 24004: "med-ovw", + 24005: "med-ci", + 24006: "med-net-svc", + 24242: "filesphere", + 24249: "vista-4gl", + 24321: "ild", + 24322: "hid", + 24386: "intel-rci", + 24465: "tonidods", + 24554: "binkp", + 24577: "bilobit-update", + 24676: "canditv", + 24677: "flashfiler", + 24678: "proactivate", + 24680: "tcc-http", + 24850: "assoc-disc", + 24922: "find", + 25000: "icl-twobase1", + 25001: "icl-twobase2", + 25002: "icl-twobase3", + 25003: "icl-twobase4", + 25004: "icl-twobase5", + 25005: "icl-twobase6", + 25006: "icl-twobase7", + 25007: "icl-twobase8", + 25008: "icl-twobase9", + 25009: "icl-twobase10", + 25793: "vocaltec-hos", + 25900: "tasp-net", + 25901: "niobserver", + 25902: "nilinkanalyst", + 25903: "niprobe", + 25954: "bf-game", + 25955: "bf-master", + 26000: "quake", + 26133: "scscp", + 26208: "wnn6-ds", + 26260: "ezproxy", + 26261: "ezmeeting", + 26262: "k3software-svr", + 26263: "k3software-cli", + 26486: "exoline-udp", + 26487: "exoconfig", + 26489: "exonet", + 27345: "imagepump", + 27442: "jesmsjc", + 27504: "kopek-httphead", + 27782: "ars-vista", + 27999: "tw-auth-key", + 28000: "nxlmd", + 28119: "a27-ran-ran", + 28200: "voxelstorm", + 28240: "siemensgsm", + 29167: "otmp", + 30001: "pago-services1", + 30002: "pago-services2", + 30003: "amicon-fpsu-ra", + 30004: "amicon-fpsu-s", + 30260: "kingdomsonline", + 30832: "samsung-disc", + 30999: "ovobs", + 31016: "ka-kdp", + 31029: "yawn", + 31416: "xqosd", + 31457: "tetrinet", + 31620: "lm-mon", + 31765: "gamesmith-port", + 31948: "iceedcp-tx", + 31949: "iceedcp-rx", + 32034: "iracinghelper", + 32249: "t1distproc60", + 32483: "apm-link", + 32635: "sec-ntb-clnt", + 32636: "DMExpress", + 32767: "filenet-powsrm", + 32768: "filenet-tms", + 32769: "filenet-rpc", + 32770: "filenet-nch", + 32771: "filenet-rmi", + 32772: "filenet-pa", + 32773: "filenet-cm", + 32774: "filenet-re", + 32775: "filenet-pch", + 32776: "filenet-peior", + 32777: "filenet-obrok", + 32801: "mlsn", + 32896: "idmgratm", + 33123: "aurora-balaena", + 33331: "diamondport", + 33334: "speedtrace-disc", + 33434: "traceroute", + 33656: "snip-slave", + 34249: "turbonote-2", + 34378: "p-net-local", + 34379: "p-net-remote", + 34567: "edi_service", + 34962: "profinet-rt", + 34963: "profinet-rtm", + 34964: "profinet-cm", + 34980: "ethercat", + 35001: "rt-viewer", + 35004: "rt-classmanager", + 35100: "axio-disc", + 35355: "altova-lm-disc", + 36001: "allpeers", + 36411: "wlcp", + 36865: "kastenxpipe", + 37475: "neckar", + 37654: "unisys-eportal", + 38002: "crescoctrl-disc", + 38201: "galaxy7-data", + 38202: "fairview", + 38203: "agpolicy", + 39681: "turbonote-1", + 40000: "safetynetp", + 40023: "k-patentssensor", + 40841: "cscp", + 40842: "csccredir", + 40843: "csccfirewall", + 40853: "ortec-disc", + 41111: "fs-qos", + 41230: "z-wave-s", + 41794: "crestron-cip", + 41795: "crestron-ctp", + 42508: "candp", + 42509: "candrp", + 42510: "caerpc", + 43000: "recvr-rc-disc", + 43188: "reachout", + 43189: "ndm-agent-port", + 43190: "ip-provision", + 43210: "shaperai-disc", + 43439: "eq3-config", + 43440: "ew-disc-cmd", + 43441: "ciscocsdb", + 44321: "pmcd", + 44322: "pmcdproxy", + 44544: "domiq", + 44553: "rbr-debug", + 44600: "asihpi", + 44818: "EtherNet-IP-2", + 44900: "m3da-disc", + 45000: "asmp-mon", + 45054: "invision-ag", + 45514: "cloudcheck-ping", + 45678: "eba", + 45825: "qdb2service", + 45966: "ssr-servermgr", + 46999: "mediabox", + 47000: "mbus", + 47100: "jvl-mactalk", + 47557: "dbbrowse", + 47624: "directplaysrvr", + 47806: "ap", + 47808: "bacnet", + 47809: "presonus-ucnet", + 48000: "nimcontroller", + 48001: "nimspooler", + 48002: "nimhub", + 48003: "nimgtw", + 48128: "isnetserv", + 48129: "blp5", + 48556: "com-bardac-dw", + 48619: "iqobject", + 48653: "robotraconteur", + 49001: "nusdp-disc", +} +var sctpPortNames = map[SCTPPort]string{ + 9: "discard", + 20: "ftp-data", + 21: "ftp", + 22: "ssh", + 80: "http", + 179: "bgp", + 443: "https", + 1021: "exp1", + 1022: "exp2", + 1167: "cisco-ipsla", + 1720: "h323hostcall", + 2049: "nfs", + 2225: "rcip-itu", + 2904: "m2ua", + 2905: "m3ua", + 2944: "megaco-h248", + 2945: "h248-binary", + 3097: "itu-bicc-stc", + 3565: "m2pa", + 3863: "asap-sctp", + 3864: "asap-sctp-tls", + 3868: "diameter", + 4333: "ahsp", + 4502: "a25-fap-fgw", + 4711: "trinity-dist", + 4739: "ipfix", + 4740: "ipfixs", + 5060: "sip", + 5061: "sips", + 5090: "car", + 5091: "cxtp", + 5215: "noteza", + 5445: "smbdirect", + 5672: "amqp", + 5675: "v5ua", + 5868: "diameters", + 5910: "cm", + 5911: "cpdlc", + 5912: "fis", + 5913: "ads-c", + 6704: "frc-hp", + 6705: "frc-mp", + 6706: "frc-lp", + 6970: "conductor-mpx", + 7626: "simco", + 7701: "nfapi", + 7728: "osvr", + 8471: "pim-port", + 9082: "lcs-ap", + 9084: "aurora", + 9900: "iua", + 9901: "enrp-sctp", + 9902: "enrp-sctp-tls", + 11997: "wmereceiving", + 11998: "wmedistribution", + 11999: "wmereporting", + 14001: "sua", + 20049: "nfsrdma", + 25471: "rna", + 29118: "sgsap", + 29168: "sbcap", + 29169: "iuhsctpassoc", + 30100: "rwp", + 36412: "s1-control", + 36422: "x2-control", + 36423: "slmap", + 36424: "nq-ap", + 36443: "m2ap", + 36444: "m3ap", + 36462: "xw-control", + 38412: "ng-control", + 38422: "xn-control", + 38472: "f1-control", +} diff --git a/vendor/github.com/google/gopacket/layers/icmp4.go b/vendor/github.com/google/gopacket/layers/icmp4.go new file mode 100644 index 0000000..bd3f03f --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/icmp4.go @@ -0,0 +1,267 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// Copyright 2009-2011 Andreas Krennmair. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "errors" + "fmt" + "reflect" + + "github.com/google/gopacket" +) + +const ( + ICMPv4TypeEchoReply = 0 + ICMPv4TypeDestinationUnreachable = 3 + ICMPv4TypeSourceQuench = 4 + ICMPv4TypeRedirect = 5 + ICMPv4TypeEchoRequest = 8 + ICMPv4TypeRouterAdvertisement = 9 + ICMPv4TypeRouterSolicitation = 10 + ICMPv4TypeTimeExceeded = 11 + ICMPv4TypeParameterProblem = 12 + ICMPv4TypeTimestampRequest = 13 + ICMPv4TypeTimestampReply = 14 + ICMPv4TypeInfoRequest = 15 + ICMPv4TypeInfoReply = 16 + ICMPv4TypeAddressMaskRequest = 17 + ICMPv4TypeAddressMaskReply = 18 +) + +const ( + // DestinationUnreachable + ICMPv4CodeNet = 0 + ICMPv4CodeHost = 1 + ICMPv4CodeProtocol = 2 + ICMPv4CodePort = 3 + ICMPv4CodeFragmentationNeeded = 4 + ICMPv4CodeSourceRoutingFailed = 5 + ICMPv4CodeNetUnknown = 6 + ICMPv4CodeHostUnknown = 7 + ICMPv4CodeSourceIsolated = 8 + ICMPv4CodeNetAdminProhibited = 9 + ICMPv4CodeHostAdminProhibited = 10 + ICMPv4CodeNetTOS = 11 + ICMPv4CodeHostTOS = 12 + ICMPv4CodeCommAdminProhibited = 13 + ICMPv4CodeHostPrecedence = 14 + ICMPv4CodePrecedenceCutoff = 15 + + // TimeExceeded + ICMPv4CodeTTLExceeded = 0 + ICMPv4CodeFragmentReassemblyTimeExceeded = 1 + + // ParameterProblem + ICMPv4CodePointerIndicatesError = 0 + ICMPv4CodeMissingOption = 1 + ICMPv4CodeBadLength = 2 + + // Redirect + // ICMPv4CodeNet = same as for DestinationUnreachable + // ICMPv4CodeHost = same as for DestinationUnreachable + ICMPv4CodeTOSNet = 2 + ICMPv4CodeTOSHost = 3 +) + +type icmpv4TypeCodeInfoStruct struct { + typeStr string + codeStr *map[uint8]string +} + +var ( + icmpv4TypeCodeInfo = map[uint8]icmpv4TypeCodeInfoStruct{ + ICMPv4TypeDestinationUnreachable: icmpv4TypeCodeInfoStruct{ + "DestinationUnreachable", &map[uint8]string{ + ICMPv4CodeNet: "Net", + ICMPv4CodeHost: "Host", + ICMPv4CodeProtocol: "Protocol", + ICMPv4CodePort: "Port", + ICMPv4CodeFragmentationNeeded: "FragmentationNeeded", + ICMPv4CodeSourceRoutingFailed: "SourceRoutingFailed", + ICMPv4CodeNetUnknown: "NetUnknown", + ICMPv4CodeHostUnknown: "HostUnknown", + ICMPv4CodeSourceIsolated: "SourceIsolated", + ICMPv4CodeNetAdminProhibited: "NetAdminProhibited", + ICMPv4CodeHostAdminProhibited: "HostAdminProhibited", + ICMPv4CodeNetTOS: "NetTOS", + ICMPv4CodeHostTOS: "HostTOS", + ICMPv4CodeCommAdminProhibited: "CommAdminProhibited", + ICMPv4CodeHostPrecedence: "HostPrecedence", + ICMPv4CodePrecedenceCutoff: "PrecedenceCutoff", + }, + }, + ICMPv4TypeTimeExceeded: icmpv4TypeCodeInfoStruct{ + "TimeExceeded", &map[uint8]string{ + ICMPv4CodeTTLExceeded: "TTLExceeded", + ICMPv4CodeFragmentReassemblyTimeExceeded: "FragmentReassemblyTimeExceeded", + }, + }, + ICMPv4TypeParameterProblem: icmpv4TypeCodeInfoStruct{ + "ParameterProblem", &map[uint8]string{ + ICMPv4CodePointerIndicatesError: "PointerIndicatesError", + ICMPv4CodeMissingOption: "MissingOption", + ICMPv4CodeBadLength: "BadLength", + }, + }, + ICMPv4TypeSourceQuench: icmpv4TypeCodeInfoStruct{ + "SourceQuench", nil, + }, + ICMPv4TypeRedirect: icmpv4TypeCodeInfoStruct{ + "Redirect", &map[uint8]string{ + ICMPv4CodeNet: "Net", + ICMPv4CodeHost: "Host", + ICMPv4CodeTOSNet: "TOS+Net", + ICMPv4CodeTOSHost: "TOS+Host", + }, + }, + ICMPv4TypeEchoRequest: icmpv4TypeCodeInfoStruct{ + "EchoRequest", nil, + }, + ICMPv4TypeEchoReply: icmpv4TypeCodeInfoStruct{ + "EchoReply", nil, + }, + ICMPv4TypeTimestampRequest: icmpv4TypeCodeInfoStruct{ + "TimestampRequest", nil, + }, + ICMPv4TypeTimestampReply: icmpv4TypeCodeInfoStruct{ + "TimestampReply", nil, + }, + ICMPv4TypeInfoRequest: icmpv4TypeCodeInfoStruct{ + "InfoRequest", nil, + }, + ICMPv4TypeInfoReply: icmpv4TypeCodeInfoStruct{ + "InfoReply", nil, + }, + ICMPv4TypeRouterSolicitation: icmpv4TypeCodeInfoStruct{ + "RouterSolicitation", nil, + }, + ICMPv4TypeRouterAdvertisement: icmpv4TypeCodeInfoStruct{ + "RouterAdvertisement", nil, + }, + ICMPv4TypeAddressMaskRequest: icmpv4TypeCodeInfoStruct{ + "AddressMaskRequest", nil, + }, + ICMPv4TypeAddressMaskReply: icmpv4TypeCodeInfoStruct{ + "AddressMaskReply", nil, + }, + } +) + +type ICMPv4TypeCode uint16 + +// Type returns the ICMPv4 type field. +func (a ICMPv4TypeCode) Type() uint8 { + return uint8(a >> 8) +} + +// Code returns the ICMPv4 code field. +func (a ICMPv4TypeCode) Code() uint8 { + return uint8(a) +} + +func (a ICMPv4TypeCode) String() string { + t, c := a.Type(), a.Code() + strInfo, ok := icmpv4TypeCodeInfo[t] + if !ok { + // Unknown ICMPv4 type field + return fmt.Sprintf("%d(%d)", t, c) + } + typeStr := strInfo.typeStr + if strInfo.codeStr == nil && c == 0 { + // The ICMPv4 type does not make use of the code field + return fmt.Sprintf("%s", strInfo.typeStr) + } + if strInfo.codeStr == nil && c != 0 { + // The ICMPv4 type does not make use of the code field, but it is present anyway + return fmt.Sprintf("%s(Code: %d)", typeStr, c) + } + codeStr, ok := (*strInfo.codeStr)[c] + if !ok { + // We don't know this ICMPv4 code; print the numerical value + return fmt.Sprintf("%s(Code: %d)", typeStr, c) + } + return fmt.Sprintf("%s(%s)", typeStr, codeStr) +} + +func (a ICMPv4TypeCode) GoString() string { + t := reflect.TypeOf(a) + return fmt.Sprintf("%s(%d, %d)", t.String(), a.Type(), a.Code()) +} + +// SerializeTo writes the ICMPv4TypeCode value to the 'bytes' buffer. +func (a ICMPv4TypeCode) SerializeTo(bytes []byte) { + binary.BigEndian.PutUint16(bytes, uint16(a)) +} + +// CreateICMPv4TypeCode is a convenience function to create an ICMPv4TypeCode +// gopacket type from the ICMPv4 type and code values. +func CreateICMPv4TypeCode(typ uint8, code uint8) ICMPv4TypeCode { + return ICMPv4TypeCode(binary.BigEndian.Uint16([]byte{typ, code})) +} + +// ICMPv4 is the layer for IPv4 ICMP packet data. +type ICMPv4 struct { + BaseLayer + TypeCode ICMPv4TypeCode + Checksum uint16 + Id uint16 + Seq uint16 +} + +// LayerType returns LayerTypeICMPv4. +func (i *ICMPv4) LayerType() gopacket.LayerType { return LayerTypeICMPv4 } + +// DecodeFromBytes decodes the given bytes into this layer. +func (i *ICMPv4) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 8 { + df.SetTruncated() + return errors.New("ICMP layer less then 8 bytes for ICMPv4 packet") + } + i.TypeCode = CreateICMPv4TypeCode(data[0], data[1]) + i.Checksum = binary.BigEndian.Uint16(data[2:4]) + i.Id = binary.BigEndian.Uint16(data[4:6]) + i.Seq = binary.BigEndian.Uint16(data[6:8]) + i.BaseLayer = BaseLayer{data[:8], data[8:]} + return nil +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (i *ICMPv4) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + bytes, err := b.PrependBytes(8) + if err != nil { + return err + } + i.TypeCode.SerializeTo(bytes) + binary.BigEndian.PutUint16(bytes[4:], i.Id) + binary.BigEndian.PutUint16(bytes[6:], i.Seq) + if opts.ComputeChecksums { + bytes[2] = 0 + bytes[3] = 0 + i.Checksum = tcpipChecksum(b.Bytes(), 0) + } + binary.BigEndian.PutUint16(bytes[2:], i.Checksum) + return nil +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (i *ICMPv4) CanDecode() gopacket.LayerClass { + return LayerTypeICMPv4 +} + +// NextLayerType returns the layer type contained by this DecodingLayer. +func (i *ICMPv4) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypePayload +} + +func decodeICMPv4(data []byte, p gopacket.PacketBuilder) error { + i := &ICMPv4{} + return decodingLayerDecoder(i, data, p) +} diff --git a/vendor/github.com/google/gopacket/layers/icmp6.go b/vendor/github.com/google/gopacket/layers/icmp6.go new file mode 100644 index 0000000..03a3213 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/icmp6.go @@ -0,0 +1,231 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// Copyright 2009-2011 Andreas Krennmair. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "errors" + "fmt" + "reflect" + + "github.com/google/gopacket" +) + +const ( + // The following are from RFC 4443 + ICMPv6TypeDestinationUnreachable = 1 + ICMPv6TypePacketTooBig = 2 + ICMPv6TypeTimeExceeded = 3 + ICMPv6TypeParameterProblem = 4 + ICMPv6TypeEchoRequest = 128 + ICMPv6TypeEchoReply = 129 + // The following are from RFC 4861 + ICMPv6TypeRouterSolicitation = 133 + ICMPv6TypeRouterAdvertisement = 134 + ICMPv6TypeNeighborSolicitation = 135 + ICMPv6TypeNeighborAdvertisement = 136 + ICMPv6TypeRedirect = 137 +) + +const ( + // DestinationUnreachable + ICMPv6CodeNoRouteToDst = 0 + ICMPv6CodeAdminProhibited = 1 + ICMPv6CodeBeyondScopeOfSrc = 2 + ICMPv6CodeAddressUnreachable = 3 + ICMPv6CodePortUnreachable = 4 + ICMPv6CodeSrcAddressFailedPolicy = 5 + ICMPv6CodeRejectRouteToDst = 6 + + // TimeExceeded + ICMPv6CodeHopLimitExceeded = 0 + ICMPv6CodeFragmentReassemblyTimeExceeded = 1 + + // ParameterProblem + ICMPv6CodeErroneousHeaderField = 0 + ICMPv6CodeUnrecognizedNextHeader = 1 + ICMPv6CodeUnrecognizedIPv6Option = 2 +) + +type icmpv6TypeCodeInfoStruct struct { + typeStr string + codeStr *map[uint8]string +} + +var ( + icmpv6TypeCodeInfo = map[uint8]icmpv6TypeCodeInfoStruct{ + ICMPv6TypeDestinationUnreachable: icmpv6TypeCodeInfoStruct{ + "DestinationUnreachable", &map[uint8]string{ + ICMPv6CodeNoRouteToDst: "NoRouteToDst", + ICMPv6CodeAdminProhibited: "AdminProhibited", + ICMPv6CodeBeyondScopeOfSrc: "BeyondScopeOfSrc", + ICMPv6CodeAddressUnreachable: "AddressUnreachable", + ICMPv6CodePortUnreachable: "PortUnreachable", + ICMPv6CodeSrcAddressFailedPolicy: "SrcAddressFailedPolicy", + ICMPv6CodeRejectRouteToDst: "RejectRouteToDst", + }, + }, + ICMPv6TypePacketTooBig: icmpv6TypeCodeInfoStruct{ + "PacketTooBig", nil, + }, + ICMPv6TypeTimeExceeded: icmpv6TypeCodeInfoStruct{ + "TimeExceeded", &map[uint8]string{ + ICMPv6CodeHopLimitExceeded: "HopLimitExceeded", + ICMPv6CodeFragmentReassemblyTimeExceeded: "FragmentReassemblyTimeExceeded", + }, + }, + ICMPv6TypeParameterProblem: icmpv6TypeCodeInfoStruct{ + "ParameterProblem", &map[uint8]string{ + ICMPv6CodeErroneousHeaderField: "ErroneousHeaderField", + ICMPv6CodeUnrecognizedNextHeader: "UnrecognizedNextHeader", + ICMPv6CodeUnrecognizedIPv6Option: "UnrecognizedIPv6Option", + }, + }, + ICMPv6TypeEchoRequest: icmpv6TypeCodeInfoStruct{ + "EchoRequest", nil, + }, + ICMPv6TypeEchoReply: icmpv6TypeCodeInfoStruct{ + "EchoReply", nil, + }, + ICMPv6TypeRouterSolicitation: icmpv6TypeCodeInfoStruct{ + "RouterSolicitation", nil, + }, + ICMPv6TypeRouterAdvertisement: icmpv6TypeCodeInfoStruct{ + "RouterAdvertisement", nil, + }, + ICMPv6TypeNeighborSolicitation: icmpv6TypeCodeInfoStruct{ + "NeighborSolicitation", nil, + }, + ICMPv6TypeNeighborAdvertisement: icmpv6TypeCodeInfoStruct{ + "NeighborAdvertisement", nil, + }, + ICMPv6TypeRedirect: icmpv6TypeCodeInfoStruct{ + "Redirect", nil, + }, + } +) + +type ICMPv6TypeCode uint16 + +// Type returns the ICMPv6 type field. +func (a ICMPv6TypeCode) Type() uint8 { + return uint8(a >> 8) +} + +// Code returns the ICMPv6 code field. +func (a ICMPv6TypeCode) Code() uint8 { + return uint8(a) +} + +func (a ICMPv6TypeCode) String() string { + t, c := a.Type(), a.Code() + strInfo, ok := icmpv6TypeCodeInfo[t] + if !ok { + // Unknown ICMPv6 type field + return fmt.Sprintf("%d(%d)", t, c) + } + typeStr := strInfo.typeStr + if strInfo.codeStr == nil && c == 0 { + // The ICMPv6 type does not make use of the code field + return fmt.Sprintf("%s", strInfo.typeStr) + } + if strInfo.codeStr == nil && c != 0 { + // The ICMPv6 type does not make use of the code field, but it is present anyway + return fmt.Sprintf("%s(Code: %d)", typeStr, c) + } + codeStr, ok := (*strInfo.codeStr)[c] + if !ok { + // We don't know this ICMPv6 code; print the numerical value + return fmt.Sprintf("%s(Code: %d)", typeStr, c) + } + return fmt.Sprintf("%s(%s)", typeStr, codeStr) +} + +func (a ICMPv6TypeCode) GoString() string { + t := reflect.TypeOf(a) + return fmt.Sprintf("%s(%d, %d)", t.String(), a.Type(), a.Code()) +} + +// SerializeTo writes the ICMPv6TypeCode value to the 'bytes' buffer. +func (a ICMPv6TypeCode) SerializeTo(bytes []byte) { + binary.BigEndian.PutUint16(bytes, uint16(a)) +} + +// CreateICMPv6TypeCode is a convenience function to create an ICMPv6TypeCode +// gopacket type from the ICMPv6 type and code values. +func CreateICMPv6TypeCode(typ uint8, code uint8) ICMPv6TypeCode { + return ICMPv6TypeCode(binary.BigEndian.Uint16([]byte{typ, code})) +} + +// ICMPv6 is the layer for IPv6 ICMP packet data +type ICMPv6 struct { + BaseLayer + TypeCode ICMPv6TypeCode + Checksum uint16 + TypeBytes []byte + tcpipchecksum +} + +// LayerType returns LayerTypeICMPv6. +func (i *ICMPv6) LayerType() gopacket.LayerType { return LayerTypeICMPv6 } + +// DecodeFromBytes decodes the given bytes into this layer. +func (i *ICMPv6) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 8 { + df.SetTruncated() + return errors.New("ICMP layer less then 8 bytes for ICMPv6 packet") + } + i.TypeCode = CreateICMPv6TypeCode(data[0], data[1]) + i.Checksum = binary.BigEndian.Uint16(data[2:4]) + i.TypeBytes = data[4:8] + i.BaseLayer = BaseLayer{data[:8], data[8:]} + return nil +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (i *ICMPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + if i.TypeBytes == nil { + i.TypeBytes = lotsOfZeros[:4] + } else if len(i.TypeBytes) != 4 { + return fmt.Errorf("invalid type bytes for ICMPv6 packet: %v", i.TypeBytes) + } + bytes, err := b.PrependBytes(8) + if err != nil { + return err + } + i.TypeCode.SerializeTo(bytes) + copy(bytes[4:8], i.TypeBytes) + if opts.ComputeChecksums { + bytes[2] = 0 + bytes[3] = 0 + csum, err := i.computeChecksum(b.Bytes(), IPProtocolICMPv6) + if err != nil { + return err + } + i.Checksum = csum + } + binary.BigEndian.PutUint16(bytes[2:], i.Checksum) + return nil +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (i *ICMPv6) CanDecode() gopacket.LayerClass { + return LayerTypeICMPv6 +} + +// NextLayerType returns the layer type contained by this DecodingLayer. +func (i *ICMPv6) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypePayload +} + +func decodeICMPv6(data []byte, p gopacket.PacketBuilder) error { + i := &ICMPv6{} + return decodingLayerDecoder(i, data, p) +} diff --git a/vendor/github.com/google/gopacket/layers/icmp6_test.go b/vendor/github.com/google/gopacket/layers/icmp6_test.go new file mode 100644 index 0000000..4a6d248 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/icmp6_test.go @@ -0,0 +1,84 @@ +// Copyright 2012, Google, Inc. All rights reserved. +// Copyright 2009-2011 Andreas Krennmair. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "github.com/google/gopacket" + "net" + "reflect" + "testing" +) + +// testPacketICMPv6 is the packet: +// 10:48:30.088384 IP6 2620:0:1005:0:26be:5ff:fe27:b17 > fe80::21f:caff:feb3:7640: ICMP6, neighbor advertisement, tgt is 2620:0:1005:0:26be:5ff:fe27:b17, length 24 +// 0x0000: 001f cab3 7640 24be 0527 0b17 86dd 6000 ....v@$..'....`. +// 0x0010: 0000 0018 3aff 2620 0000 1005 0000 26be ....:.&.......&. +// 0x0020: 05ff fe27 0b17 fe80 0000 0000 0000 021f ...'............ +// 0x0030: caff feb3 7640 8800 1ed6 4000 0000 2620 ....v@....@...&. +// 0x0040: 0000 1005 0000 26be 05ff fe27 0b17 ......&....'.. +var testPacketICMPv6 = []byte{ + 0x00, 0x1f, 0xca, 0xb3, 0x76, 0x40, 0x24, 0xbe, 0x05, 0x27, 0x0b, 0x17, 0x86, 0xdd, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x3a, 0xff, 0x26, 0x20, 0x00, 0x00, 0x10, 0x05, 0x00, 0x00, 0x26, 0xbe, + 0x05, 0xff, 0xfe, 0x27, 0x0b, 0x17, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1f, + 0xca, 0xff, 0xfe, 0xb3, 0x76, 0x40, 0x88, 0x00, 0x1e, 0xd6, 0x40, 0x00, 0x00, 0x00, 0x26, 0x20, + 0x00, 0x00, 0x10, 0x05, 0x00, 0x00, 0x26, 0xbe, 0x05, 0xff, 0xfe, 0x27, 0x0b, 0x17, +} + +func TestPacketICMPv6(t *testing.T) { + p := gopacket.NewPacket(testPacketICMPv6, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv6, LayerTypeICMPv6, gopacket.LayerTypePayload}, t) + if got, ok := p.Layer(LayerTypeIPv6).(*IPv6); ok { + want := &IPv6{ + BaseLayer: BaseLayer{ + Contents: []byte{0x60, 0x0, 0x0, 0x0, 0x0, 0x18, + 0x3a, 0xff, 0x26, 0x20, 0x0, 0x0, 0x10, 0x5, 0x0, 0x0, 0x26, 0xbe, 0x5, + 0xff, 0xfe, 0x27, 0xb, 0x17, 0xfe, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x1f, 0xca, 0xff, 0xfe, 0xb3, 0x76, 0x40}, + Payload: []byte{0x88, 0x0, 0x1e, 0xd6, 0x40, 0x0, 0x0, 0x0, 0x26, 0x20, + 0x0, 0x0, 0x10, 0x5, 0x0, 0x0, 0x26, 0xbe, 0x5, 0xff, 0xfe, 0x27, 0xb, + 0x17}, + }, + Version: 6, + TrafficClass: 0, + FlowLabel: 0, + Length: 24, + NextHeader: IPProtocolICMPv6, + HopLimit: 255, + SrcIP: net.IP{0x26, 0x20, 0x0, 0x0, 0x10, 0x5, 0x0, 0x0, 0x26, 0xbe, 0x5, 0xff, 0xfe, 0x27, 0xb, 0x17}, + DstIP: net.IP{0xfe, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x1f, 0xca, 0xff, 0xfe, 0xb3, 0x76, 0x40}, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("IPv6 packet processing failed:\ngot :\n%#v\n\nwant :\n%#v\n\n", got, want) + } + } else { + t.Error("No IPv6 layer type found in packet") + } + if got, ok := p.Layer(LayerTypeICMPv6).(*ICMPv6); ok { + want := &ICMPv6{ + BaseLayer: BaseLayer{ + Contents: []byte{0x88, 0x0, 0x1e, 0xd6, 0x40, 0x0, 0x0, 0x0}, + Payload: []byte{0x26, 0x20, 0x0, 0x0, 0x10, + 0x5, 0x0, 0x0, 0x26, 0xbe, 0x5, 0xff, 0xfe, 0x27, 0xb, 0x17}, + }, + TypeCode: 0x8800, + Checksum: 0x1ed6, + TypeBytes: []byte{0x40, 0x0, 0x0, 0x0}, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("ICMPv6 packet processing failed:\ngot :\n%#v\n\nwant :\n%#v\n\n", got, want) + } + if got.TypeCode.String() != "NeighborAdvertisement" { + t.Errorf("ICMPv6 type code, got %q want 'NeighborAdvertisement'", got.TypeCode.String()) + } + } else { + t.Error("No ICMPv6 layer type found in packet") + } +} diff --git a/vendor/github.com/google/gopacket/layers/igmp.go b/vendor/github.com/google/gopacket/layers/igmp.go new file mode 100644 index 0000000..d008415 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/igmp.go @@ -0,0 +1,355 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// Copyright 2009-2011 Andreas Krennmair. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "errors" + "net" + "time" + + "github.com/google/gopacket" +) + +type IGMPType uint8 + +const ( + IGMPMembershipQuery IGMPType = 0x11 // General or group specific query + IGMPMembershipReportV1 IGMPType = 0x12 // Version 1 Membership Report + IGMPMembershipReportV2 IGMPType = 0x16 // Version 2 Membership Report + IGMPLeaveGroup IGMPType = 0x17 // Leave Group + IGMPMembershipReportV3 IGMPType = 0x22 // Version 3 Membership Report +) + +// String conversions for IGMP message types +func (i IGMPType) String() string { + switch i { + case IGMPMembershipQuery: + return "IGMP Membership Query" + case IGMPMembershipReportV1: + return "IGMPv1 Membership Report" + case IGMPMembershipReportV2: + return "IGMPv2 Membership Report" + case IGMPMembershipReportV3: + return "IGMPv3 Membership Report" + case IGMPLeaveGroup: + return "Leave Group" + default: + return "" + } +} + +type IGMPv3GroupRecordType uint8 + +const ( + IGMPIsIn IGMPv3GroupRecordType = 0x01 // Type MODE_IS_INCLUDE, source addresses x + IGMPIsEx IGMPv3GroupRecordType = 0x02 // Type MODE_IS_EXCLUDE, source addresses x + IGMPToIn IGMPv3GroupRecordType = 0x03 // Type CHANGE_TO_INCLUDE_MODE, source addresses x + IGMPToEx IGMPv3GroupRecordType = 0x04 // Type CHANGE_TO_EXCLUDE_MODE, source addresses x + IGMPAllow IGMPv3GroupRecordType = 0x05 // Type ALLOW_NEW_SOURCES, source addresses x + IGMPBlock IGMPv3GroupRecordType = 0x06 // Type BLOCK_OLD_SOURCES, source addresses x +) + +func (i IGMPv3GroupRecordType) String() string { + switch i { + case IGMPIsIn: + return "MODE_IS_INCLUDE" + case IGMPIsEx: + return "MODE_IS_EXCLUDE" + case IGMPToIn: + return "CHANGE_TO_INCLUDE_MODE" + case IGMPToEx: + return "CHANGE_TO_EXCLUDE_MODE" + case IGMPAllow: + return "ALLOW_NEW_SOURCES" + case IGMPBlock: + return "BLOCK_OLD_SOURCES" + default: + return "" + } +} + +// IGMP represents an IGMPv3 message. +type IGMP struct { + BaseLayer + Type IGMPType + MaxResponseTime time.Duration + Checksum uint16 + GroupAddress net.IP + SupressRouterProcessing bool + RobustnessValue uint8 + IntervalTime time.Duration + SourceAddresses []net.IP + NumberOfGroupRecords uint16 + NumberOfSources uint16 + GroupRecords []IGMPv3GroupRecord + Version uint8 // IGMP protocol version +} + +// IGMPv1or2 stores header details for an IGMPv1 or IGMPv2 packet. +// +// 0 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Type | Max Resp Time | Checksum | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Group Address | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +type IGMPv1or2 struct { + BaseLayer + Type IGMPType // IGMP message type + MaxResponseTime time.Duration // meaningful only in Membership Query messages + Checksum uint16 // 16-bit checksum of entire ip payload + GroupAddress net.IP // either 0 or an IP multicast address + Version uint8 +} + +// decodeResponse dissects IGMPv1 or IGMPv2 packet. +func (i *IGMPv1or2) decodeResponse(data []byte) error { + if len(data) < 8 { + return errors.New("IGMP packet too small") + } + + i.MaxResponseTime = igmpTimeDecode(data[1]) + i.Checksum = binary.BigEndian.Uint16(data[2:4]) + i.GroupAddress = net.IP(data[4:8]) + + return nil +} + +// 0 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Type = 0x22 | Reserved | Checksum | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Reserved | Number of Group Records (M) | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | | +// . Group Record [1] . +// | | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | | +// . Group Record [2] . +// | | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | | +// . Group Record [M] . +// | | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Record Type | Aux Data Len | Number of Sources (N) | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Multicast Address | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Source Address [1] | +// +- -+ +// | Source Address [2] | +// +- -+ +// | Source Address [N] | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | | +// . Auxiliary Data . +// | | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +// IGMPv3GroupRecord stores individual group records for a V3 Membership Report message. +type IGMPv3GroupRecord struct { + Type IGMPv3GroupRecordType + AuxDataLen uint8 // this should always be 0 as per IGMPv3 spec. + NumberOfSources uint16 + MulticastAddress net.IP + SourceAddresses []net.IP + AuxData uint32 // NOT USED +} + +func (i *IGMP) decodeIGMPv3MembershipReport(data []byte) error { + if len(data) < 8 { + return errors.New("IGMPv3 Membership Report too small #1") + } + + i.Checksum = binary.BigEndian.Uint16(data[2:4]) + i.NumberOfGroupRecords = binary.BigEndian.Uint16(data[6:8]) + + recordOffset := 8 + for j := 0; j < int(i.NumberOfGroupRecords); j++ { + if len(data) < recordOffset+8 { + return errors.New("IGMPv3 Membership Report too small #2") + } + + var gr IGMPv3GroupRecord + gr.Type = IGMPv3GroupRecordType(data[recordOffset]) + gr.AuxDataLen = data[recordOffset+1] + gr.NumberOfSources = binary.BigEndian.Uint16(data[recordOffset+2 : recordOffset+4]) + gr.MulticastAddress = net.IP(data[recordOffset+4 : recordOffset+8]) + + if len(data) < recordOffset+8+int(gr.NumberOfSources)*4 { + return errors.New("IGMPv3 Membership Report too small #3") + } + + // append source address records. + for i := 0; i < int(gr.NumberOfSources); i++ { + sourceAddr := net.IP(data[recordOffset+8+i*4 : recordOffset+12+i*4]) + gr.SourceAddresses = append(gr.SourceAddresses, sourceAddr) + } + + i.GroupRecords = append(i.GroupRecords, gr) + recordOffset += 8 + 4*int(gr.NumberOfSources) + } + return nil +} + +// 0 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Type = 0x11 | Max Resp Code | Checksum | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Group Address | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Resv |S| QRV | QQIC | Number of Sources (N) | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Source Address [1] | +// +- -+ +// | Source Address [2] | +// +- . -+ +// | Source Address [N] | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// decodeIGMPv3MembershipQuery parses the IGMPv3 message of type 0x11 +func (i *IGMP) decodeIGMPv3MembershipQuery(data []byte) error { + if len(data) < 12 { + return errors.New("IGMPv3 Membership Query too small #1") + } + + i.MaxResponseTime = igmpTimeDecode(data[1]) + i.Checksum = binary.BigEndian.Uint16(data[2:4]) + i.SupressRouterProcessing = data[8]&0x8 != 0 + i.GroupAddress = net.IP(data[4:8]) + i.RobustnessValue = data[8] & 0x7 + i.IntervalTime = igmpTimeDecode(data[9]) + i.NumberOfSources = binary.BigEndian.Uint16(data[10:12]) + + if len(data) < 12+int(i.NumberOfSources)*4 { + return errors.New("IGMPv3 Membership Query too small #2") + } + + for j := 0; j < int(i.NumberOfSources); j++ { + i.SourceAddresses = append(i.SourceAddresses, net.IP(data[12+j*4:16+j*4])) + } + + return nil +} + +// igmpTimeDecode decodes the duration created by the given byte, using the +// algorithm in http://www.rfc-base.org/txt/rfc-3376.txt section 4.1.1. +func igmpTimeDecode(t uint8) time.Duration { + if t&0x80 == 0 { + return time.Millisecond * 100 * time.Duration(t) + } + mant := (t & 0x70) >> 4 + exp := t & 0x0F + return time.Millisecond * 100 * time.Duration((mant|0x10)<<(exp+3)) +} + +// LayerType returns LayerTypeIGMP for the V1,2,3 message protocol formats. +func (i *IGMP) LayerType() gopacket.LayerType { return LayerTypeIGMP } +func (i *IGMPv1or2) LayerType() gopacket.LayerType { return LayerTypeIGMP } + +func (i *IGMPv1or2) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 8 { + return errors.New("IGMP Packet too small") + } + + i.Type = IGMPType(data[0]) + i.MaxResponseTime = igmpTimeDecode(data[1]) + i.Checksum = binary.BigEndian.Uint16(data[2:4]) + i.GroupAddress = net.IP(data[4:8]) + + return nil +} + +func (i *IGMPv1or2) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypeZero +} + +func (i *IGMPv1or2) CanDecode() gopacket.LayerClass { + return LayerTypeIGMP +} + +// DecodeFromBytes decodes the given bytes into this layer. +func (i *IGMP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 1 { + return errors.New("IGMP packet is too small") + } + + // common IGMP header values between versions 1..3 of IGMP specification.. + i.Type = IGMPType(data[0]) + + switch i.Type { + case IGMPMembershipQuery: + i.decodeIGMPv3MembershipQuery(data) + case IGMPMembershipReportV3: + i.decodeIGMPv3MembershipReport(data) + default: + return errors.New("unsupported IGMP type") + } + + return nil +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (i *IGMP) CanDecode() gopacket.LayerClass { + return LayerTypeIGMP +} + +// NextLayerType returns the layer type contained by this DecodingLayer. +func (i *IGMP) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypeZero +} + +// decodeIGMP will parse IGMP v1,2 or 3 protocols. Checks against the +// IGMP type are performed against byte[0], logic then iniitalizes and +// passes the appropriate struct (IGMP or IGMPv1or2) to +// decodingLayerDecoder. +func decodeIGMP(data []byte, p gopacket.PacketBuilder) error { + if len(data) < 1 { + return errors.New("IGMP packet is too small") + } + + // byte 0 contains IGMP message type. + switch IGMPType(data[0]) { + case IGMPMembershipQuery: + // IGMPv3 Membership Query payload is >= 12 + if len(data) >= 12 { + i := &IGMP{Version: 3} + return decodingLayerDecoder(i, data, p) + } else if len(data) == 8 { + i := &IGMPv1or2{} + if data[1] == 0x00 { + i.Version = 1 // IGMPv1 has a query length of 8 and MaxResp = 0 + } else { + i.Version = 2 // IGMPv2 has a query length of 8 and MaxResp != 0 + } + + return decodingLayerDecoder(i, data, p) + } + case IGMPMembershipReportV3: + i := &IGMP{Version: 3} + return decodingLayerDecoder(i, data, p) + case IGMPMembershipReportV1: + i := &IGMPv1or2{Version: 1} + return decodingLayerDecoder(i, data, p) + case IGMPLeaveGroup, IGMPMembershipReportV2: + // leave group and Query Report v2 used in IGMPv2 only. + i := &IGMPv1or2{Version: 2} + return decodingLayerDecoder(i, data, p) + default: + } + + return errors.New("Unable to determine IGMP type.") +} diff --git a/vendor/github.com/google/gopacket/layers/igmp_test.go b/vendor/github.com/google/gopacket/layers/igmp_test.go new file mode 100644 index 0000000..923356d --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/igmp_test.go @@ -0,0 +1,171 @@ +// Copyright 2016, Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "testing" + + "github.com/google/gopacket" +) + +// igmpv1MembershipReportPacket is the packet: +// 02:45:36.033916 IP 10.60.0.132 > 224.0.1.60: igmp v1 report 224.0.1.60 +// 0x0000: 0100 5e00 013c 0030 c1bf 5755 0800 4500 ..^..<.0..WU..E. +// 0x0010: 001c 6a7f 0000 0102 6365 0a3c 0084 e000 ..j.....ce.<.... +// 0x0020: 013c 1200 0cc3 e000 013c 0000 0000 0000 .<.......<...... +// 0x0030: ffff ffff ffff 0452 0000 0000 .......R.... +var igmpv1MembershipReportPacket = []byte{ + 0x01, 0x00, 0x5e, 0x00, 0x01, 0x3c, 0x00, 0x30, 0xc1, 0xbf, 0x57, 0x55, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x1c, 0x6a, 0x7f, 0x00, 0x00, 0x01, 0x02, 0x63, 0x65, 0x0a, 0x3c, 0x00, 0x84, 0xe0, 0x00, + 0x01, 0x3c, 0x12, 0x00, 0x0c, 0xc3, 0xe0, 0x00, 0x01, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x04, 0x52, 0x00, 0x00, 0x00, 0x00, +} + +func TestIGMPv1MembershipReportPacket(t *testing.T) { + p := gopacket.NewPacket(igmpv1MembershipReportPacket, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeIGMP}, t) + + igmp := p.Layer(LayerTypeIGMP).(*IGMPv1or2) + if igmp.Type != IGMPMembershipReportV1 { + t.Fatal("Invalid IGMP type") + } +} + +func BenchmarkDecodeigmpv1MembershipReportPacket(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(igmpv1MembershipReportPacket, LinkTypeEthernet, gopacket.NoCopy) + } +} + +// igmpv2MembershipQueryPacket is the packet: +// 02:45:28.071636 IP 10.60.0.189 > 224.0.0.1: igmp query v2 +// 0x0000: 0100 5e00 0001 0001 636f c800 0800 45c0 ..^.....co....E. +// 0x0010: 001c 0153 0000 0102 ccd3 0a3c 00bd e000 ...S.......<.... +// 0x0020: 0001 1164 ee9b 0000 0000 0000 0000 0000 ...d............ +// 0x0030: 0000 0000 0000 0000 0000 0000 ............ +var igmpv2MembershipQueryPacket = []byte{ + 0x01, 0x00, 0x5e, 0x00, 0x00, 0x01, 0x00, 0x01, 0x63, 0x6f, 0xc8, 0x00, 0x08, 0x00, 0x45, 0xc0, + 0x00, 0x1c, 0x01, 0x53, 0x00, 0x00, 0x01, 0x02, 0xcc, 0xd3, 0x0a, 0x3c, 0x00, 0xbd, 0xe0, 0x00, + 0x00, 0x01, 0x11, 0x64, 0xee, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +} + +func TestIGMPv2MembershipQuery(t *testing.T) { + p := gopacket.NewPacket(igmpv2MembershipQueryPacket, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeIGMP}, t) + + igmp := p.Layer(LayerTypeIGMP).(*IGMPv1or2) + if igmp.Type != IGMPMembershipQuery { + t.Fatal("Invalid IGMP type") + } +} +func BenchmarkDecodeigmpv2MembershipQueryPacket(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(igmpv2MembershipQueryPacket, LinkTypeEthernet, gopacket.NoCopy) + } +} + +// igmpv2MembershipReportPacket is the packet: +// 02:47:32.417288 IP 10.60.5.103 > 239.255.255.253: igmp v2 report 239.255.255.253 +// 0x0000: 0100 5e7f fffd 0015 58dc d9f6 0800 4600 ..^.....X.....F. +// 0x0010: 0020 79f0 0000 0102 ab47 0a3c 0567 efff ..y......G.<.g.. +// 0x0020: fffd 9404 0000 1600 fa01 efff fffd 0000 ................ +// 0x0030: 0000 0000 0000 0000 0000 0000 ............ +var igmpv2MembershipReportPacket = []byte{ + 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xfd, 0x00, 0x15, 0x58, 0xdc, 0xd9, 0xf6, 0x08, 0x00, 0x46, 0x00, + 0x00, 0x20, 0x79, 0xf0, 0x00, 0x00, 0x01, 0x02, 0xab, 0x47, 0x0a, 0x3c, 0x05, 0x67, 0xef, 0xff, + 0xff, 0xfd, 0x94, 0x04, 0x00, 0x00, 0x16, 0x00, 0xfa, 0x01, 0xef, 0xff, 0xff, 0xfd, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +} + +func TestIGMPv2MembershipReport(t *testing.T) { + p := gopacket.NewPacket(igmpv2MembershipReportPacket, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeIGMP}, t) + + igmp := p.Layer(LayerTypeIGMP).(*IGMPv1or2) + if igmp.Type != IGMPMembershipReportV2 { + t.Fatal("Invalid IGMP type") + } +} +func BenchmarkDecodeigmpv2MembershipReportPacket(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(igmpv2MembershipReportPacket, LinkTypeEthernet, gopacket.NoCopy) + } +} + +// igmp3v3MembershipQueryPacket is the packet: +// 10:07:30.488511 IP 192.168.1.254 > 224.0.0.1: igmp query v3 [max resp time 2.4s] +// 0x0000: 0100 5e00 0001 0026 446c 1eda 0800 46c0 ..^....&Dl....F. +// 0x0010: 0024 17f1 4000 0102 297b c0a8 01fe e000 .$..@...){...... +// 0x0020: 0001 9404 0000 1118 ecd3 0000 0000 0214 ................ +// 0x0030: 0000 0000 0000 0000 0000 0000 ............ +var igmp3v3MembershipQueryPacket = []byte{ + 0x01, 0x00, 0x5e, 0x00, 0x00, 0x01, 0x00, 0x26, 0x44, 0x6c, 0x1e, 0xda, 0x08, 0x00, 0x46, 0xc0, + 0x00, 0x24, 0x17, 0xf1, 0x40, 0x00, 0x01, 0x02, 0x29, 0x7b, 0xc0, 0xa8, 0x01, 0xfe, 0xe0, 0x00, + 0x00, 0x01, 0x94, 0x04, 0x00, 0x00, 0x11, 0x18, 0xec, 0xd3, 0x00, 0x00, 0x00, 0x00, 0x02, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +} + +func TestIGMPv3MembershipQuery(t *testing.T) { + p := gopacket.NewPacket(igmp3v3MembershipQueryPacket, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeIGMP}, t) + + igmp := p.Layer(LayerTypeIGMP).(*IGMP) + if igmp.Type != IGMPMembershipQuery { + t.Fatal("Invalid IGMP type") + } +} + +func BenchmarkDecodeigmp3v3MembershipQueryPacket(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(igmp3v3MembershipQueryPacket, LinkTypeEthernet, gopacket.NoCopy) + } +} + +// igmpv3MembershipReport2Records is the packet: +// 10:07:29.756202 IP 192.168.1.66 > 224.0.0.22: igmp v3 report, 2 group record(s) +// 0x0000: 0100 5e00 0016 0025 2e51 c381 0800 4658 ..^....%.Q....FX +// 0x0010: 0030 013c 0000 0102 8133 c0a8 0142 e000 .0.<.....3...B.. +// 0x0020: 0016 9404 0000 2200 f33c 0000 0002 0200 ......"..<...... +// 0x0030: 0000 efc3 0702 0200 0000 efff fffa .............. +var igmpv3MembershipReport2Records = []byte{ + 0x01, 0x00, 0x5e, 0x00, 0x00, 0x16, 0x00, 0x25, 0x2e, 0x51, 0xc3, 0x81, 0x08, 0x00, 0x46, 0x58, + 0x00, 0x30, 0x01, 0x3c, 0x00, 0x00, 0x01, 0x02, 0x81, 0x33, 0xc0, 0xa8, 0x01, 0x42, 0xe0, 0x00, + 0x00, 0x16, 0x94, 0x04, 0x00, 0x00, 0x22, 0x00, 0xf3, 0x3c, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, + 0x00, 0x00, 0xef, 0xc3, 0x07, 0x02, 0x02, 0x00, 0x00, 0x00, 0xef, 0xff, 0xff, 0xfa, +} + +func TestIGMPv3MembershipReport2Records(t *testing.T) { + p := gopacket.NewPacket(igmpv3MembershipReport2Records, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeIGMP}, t) + + igmp := p.Layer(LayerTypeIGMP).(*IGMP) + if igmp.Type != IGMPMembershipReportV3 { + t.Fatal("Invalid IGMP type") + } +} + +func BenchmarkDecodeigmpv3MembershipReport2Records(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(igmpv3MembershipReport2Records, LinkTypeEthernet, gopacket.NoCopy) + } +} diff --git a/vendor/github.com/google/gopacket/layers/ip4.go b/vendor/github.com/google/gopacket/layers/ip4.go new file mode 100644 index 0000000..3f31b27 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/ip4.go @@ -0,0 +1,311 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// Copyright 2009-2011 Andreas Krennmair. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "errors" + "fmt" + "net" + "strings" + + "github.com/google/gopacket" +) + +type IPv4Flag uint8 + +const ( + IPv4EvilBit IPv4Flag = 1 << 2 // http://tools.ietf.org/html/rfc3514 ;) + IPv4DontFragment IPv4Flag = 1 << 1 + IPv4MoreFragments IPv4Flag = 1 << 0 +) + +func (f IPv4Flag) String() string { + var s []string + if f&IPv4EvilBit != 0 { + s = append(s, "Evil") + } + if f&IPv4DontFragment != 0 { + s = append(s, "DF") + } + if f&IPv4MoreFragments != 0 { + s = append(s, "MF") + } + return strings.Join(s, "|") +} + +// IPv4 is the header of an IP packet. +type IPv4 struct { + BaseLayer + Version uint8 + IHL uint8 + TOS uint8 + Length uint16 + Id uint16 + Flags IPv4Flag + FragOffset uint16 + TTL uint8 + Protocol IPProtocol + Checksum uint16 + SrcIP net.IP + DstIP net.IP + Options []IPv4Option + Padding []byte +} + +// LayerType returns LayerTypeIPv4 +func (i *IPv4) LayerType() gopacket.LayerType { return LayerTypeIPv4 } +func (i *IPv4) NetworkFlow() gopacket.Flow { + return gopacket.NewFlow(EndpointIPv4, i.SrcIP, i.DstIP) +} + +type IPv4Option struct { + OptionType uint8 + OptionLength uint8 + OptionData []byte +} + +func (i IPv4Option) String() string { + return fmt.Sprintf("IPv4Option(%v:%v)", i.OptionType, i.OptionData) +} + +// for the current ipv4 options, return the number of bytes (including +// padding that the options used) +func (ip *IPv4) getIPv4OptionSize() uint8 { + optionSize := uint8(0) + for _, opt := range ip.Options { + switch opt.OptionType { + case 0: + // this is the end of option lists + optionSize++ + case 1: + // this is the padding + optionSize++ + default: + optionSize += opt.OptionLength + + } + } + // make sure the options are aligned to 32 bit boundary + if (optionSize % 4) != 0 { + optionSize += 4 - (optionSize % 4) + } + return optionSize +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +func (ip *IPv4) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + optionLength := ip.getIPv4OptionSize() + bytes, err := b.PrependBytes(20 + int(optionLength)) + if err != nil { + return err + } + if opts.FixLengths { + ip.IHL = 5 + (optionLength / 4) + ip.Length = uint16(len(b.Bytes())) + } + bytes[0] = (ip.Version << 4) | ip.IHL + bytes[1] = ip.TOS + binary.BigEndian.PutUint16(bytes[2:], ip.Length) + binary.BigEndian.PutUint16(bytes[4:], ip.Id) + binary.BigEndian.PutUint16(bytes[6:], ip.flagsfrags()) + bytes[8] = ip.TTL + bytes[9] = byte(ip.Protocol) + if err := ip.AddressTo4(); err != nil { + return err + } + copy(bytes[12:16], ip.SrcIP) + copy(bytes[16:20], ip.DstIP) + + curLocation := 20 + // Now, we will encode the options + for _, opt := range ip.Options { + switch opt.OptionType { + case 0: + // this is the end of option lists + bytes[curLocation] = 0 + curLocation++ + case 1: + // this is the padding + bytes[curLocation] = 1 + curLocation++ + default: + bytes[curLocation] = opt.OptionType + bytes[curLocation+1] = opt.OptionLength + + // sanity checking to protect us from buffer overrun + if len(opt.OptionData) > int(opt.OptionLength-2) { + return errors.New("option length is smaller than length of option data") + } + copy(bytes[curLocation+2:curLocation+int(opt.OptionLength)], opt.OptionData) + curLocation += int(opt.OptionLength) + } + } + + if opts.ComputeChecksums { + ip.Checksum = checksum(bytes) + } + binary.BigEndian.PutUint16(bytes[10:], ip.Checksum) + return nil +} + +func checksum(bytes []byte) uint16 { + // Clear checksum bytes + bytes[10] = 0 + bytes[11] = 0 + + // Compute checksum + var csum uint32 + for i := 0; i < len(bytes); i += 2 { + csum += uint32(bytes[i]) << 8 + csum += uint32(bytes[i+1]) + } + for { + // Break when sum is less or equals to 0xFFFF + if csum <= 65535 { + break + } + // Add carry to the sum + csum = (csum >> 16) + uint32(uint16(csum)) + } + // Flip all the bits + return ^uint16(csum) +} + +func (ip *IPv4) flagsfrags() (ff uint16) { + ff |= uint16(ip.Flags) << 13 + ff |= ip.FragOffset + return +} + +// DecodeFromBytes decodes the given bytes into this layer. +func (ip *IPv4) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + flagsfrags := binary.BigEndian.Uint16(data[6:8]) + + ip.Version = uint8(data[0]) >> 4 + ip.IHL = uint8(data[0]) & 0x0F + ip.TOS = data[1] + ip.Length = binary.BigEndian.Uint16(data[2:4]) + ip.Id = binary.BigEndian.Uint16(data[4:6]) + ip.Flags = IPv4Flag(flagsfrags >> 13) + ip.FragOffset = flagsfrags & 0x1FFF + ip.TTL = data[8] + ip.Protocol = IPProtocol(data[9]) + ip.Checksum = binary.BigEndian.Uint16(data[10:12]) + ip.SrcIP = data[12:16] + ip.DstIP = data[16:20] + ip.Options = ip.Options[:0] + // Set up an initial guess for contents/payload... we'll reset these soon. + ip.BaseLayer = BaseLayer{Contents: data} + + // This code is added for the following enviroment: + // * Windows 10 with TSO option activated. ( tested on Hyper-V, RealTek ethernet driver ) + if ip.Length == 0 { + // If using TSO(TCP Segmentation Offload), length is zero. + // The actual packet length is the length of data. + ip.Length = uint16(len(data)) + } + + if ip.Length < 20 { + return fmt.Errorf("Invalid (too small) IP length (%d < 20)", ip.Length) + } else if ip.IHL < 5 { + return fmt.Errorf("Invalid (too small) IP header length (%d < 5)", ip.IHL) + } else if int(ip.IHL*4) > int(ip.Length) { + return fmt.Errorf("Invalid IP header length > IP length (%d > %d)", ip.IHL, ip.Length) + } + if cmp := len(data) - int(ip.Length); cmp > 0 { + data = data[:ip.Length] + } else if cmp < 0 { + df.SetTruncated() + if int(ip.IHL)*4 > len(data) { + return errors.New("Not all IP header bytes available") + } + } + ip.Contents = data[:ip.IHL*4] + ip.Payload = data[ip.IHL*4:] + // From here on, data contains the header options. + data = data[20 : ip.IHL*4] + // Pull out IP options + for len(data) > 0 { + if ip.Options == nil { + // Pre-allocate to avoid growing the slice too much. + ip.Options = make([]IPv4Option, 0, 4) + } + opt := IPv4Option{OptionType: data[0]} + switch opt.OptionType { + case 0: // End of options + opt.OptionLength = 1 + ip.Options = append(ip.Options, opt) + ip.Padding = data[1:] + break + case 1: // 1 byte padding + opt.OptionLength = 1 + default: + opt.OptionLength = data[1] + opt.OptionData = data[2:opt.OptionLength] + } + if len(data) >= int(opt.OptionLength) { + data = data[opt.OptionLength:] + } else { + return fmt.Errorf("IP option length exceeds remaining IP header size, option type %v length %v", opt.OptionType, opt.OptionLength) + } + ip.Options = append(ip.Options, opt) + } + return nil +} + +func (i *IPv4) CanDecode() gopacket.LayerClass { + return LayerTypeIPv4 +} + +func (i *IPv4) NextLayerType() gopacket.LayerType { + if i.Flags&IPv4MoreFragments != 0 || i.FragOffset != 0 { + return gopacket.LayerTypeFragment + } + return i.Protocol.LayerType() +} + +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 checkIPv4Address(addr net.IP) (net.IP, error) { + if c := addr.To4(); c != nil { + return c, nil + } + if len(addr) == net.IPv6len { + return nil, errors.New("address is IPv6") + } + return nil, fmt.Errorf("wrong length of %d bytes instead of %d", len(addr), net.IPv4len) +} + +func (ip *IPv4) AddressTo4() error { + var src, dst net.IP + + if addr, err := checkIPv4Address(ip.SrcIP); err != nil { + return fmt.Errorf("Invalid source IPv4 address (%s)", err) + } else { + src = addr + } + if addr, err := checkIPv4Address(ip.DstIP); err != nil { + return fmt.Errorf("Invalid destination IPv4 address (%s)", err) + } else { + dst = addr + } + ip.SrcIP = src + ip.DstIP = dst + return nil +} diff --git a/vendor/github.com/google/gopacket/layers/ip4_test.go b/vendor/github.com/google/gopacket/layers/ip4_test.go new file mode 100644 index 0000000..ec6b351 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/ip4_test.go @@ -0,0 +1,131 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +// This file tests some of the functionality provided in the ip4.go + +package layers + +import ( + "encoding/binary" + "encoding/hex" + "net" + "testing" + + "github.com/google/gopacket" +) + +// Test the function getIPv4OptionSize when the ipv4 has no options +func TestGetIPOptLengthNoOpt(t *testing.T) { + ip := IPv4{} + length := ip.getIPv4OptionSize() + if length != 0 { + t.Fatalf("Empty option list should have 0 length. Actual %d", length) + } +} + +// Test the function getIPv4OptionSize when the ipv4 has end of list option +func TestGetIPOptLengthEndOfList(t *testing.T) { + ip := IPv4{} + ip.Options = append(ip.Options, IPv4Option{OptionType: 0, OptionLength: 1}) + length := ip.getIPv4OptionSize() + if length != 4 { + t.Fatalf("After padding, the list should have 4 length. Actual %d", length) + } +} + +// Test the function getIPv4OptionSize when the ipv4 has padding and end of list option +func TestGetIPOptLengthPaddingEndOfList(t *testing.T) { + ip := IPv4{} + ip.Options = append(ip.Options, IPv4Option{OptionType: 1, OptionLength: 1}) + ip.Options = append(ip.Options, IPv4Option{OptionType: 0, OptionLength: 1}) + length := ip.getIPv4OptionSize() + if length != 4 { + t.Fatalf("After padding, the list should have 4 length. Actual %d", length) + } +} + +// Test the function getIPv4OptionSize when the ipv4 has some non-trivial option and end of list option +func TestGetIPOptLengthOptionEndOfList(t *testing.T) { + ip := IPv4{} + someByte := make([]byte, 8) + ip.Options = append(ip.Options, IPv4Option{OptionType: 2, OptionLength: 10, OptionData: someByte}) + ip.Options = append(ip.Options, IPv4Option{OptionType: 0, OptionLength: 1}) + length := ip.getIPv4OptionSize() + if length != 12 { + t.Fatalf("The list should have 12 length. Actual %d", length) + } +} + +// Tests that the Options slice is properly reset before parsing new data +func TestIPOptResetDuringDecoding(t *testing.T) { + ip := &IPv4{ + Options: []IPv4Option{{OptionType: 42, OptionLength: 4, OptionData: make([]byte, 2)}}, + } + + ipWithoutOptions := &IPv4{ + SrcIP: net.IPv4(192, 168, 1, 1), + DstIP: net.IPv4(192, 168, 1, 1), + Protocol: IPProtocolTCP, + } + + ipBytes, err := serialize(ipWithoutOptions) + + if err != nil { + t.Fatalf("Failed to serialize ip layer: %v", err) + } + + err = ip.DecodeFromBytes(ipBytes, gopacket.NilDecodeFeedback) + + if err != nil { + t.Fatalf("Failed to deserialize ip layer: %v", err) + } + + if len(ip.Options) > 0 { + t.Fatalf("Options slice has stale data from previous packet") + } + +} + +func serialize(ip *IPv4) ([]byte, error) { + buffer := gopacket.NewSerializeBuffer() + err := ip.SerializeTo(buffer, gopacket.SerializeOptions{ + FixLengths: true, + ComputeChecksums: true, + }) + return buffer.Bytes(), err +} + +// Test the function checksum +func TestChecksum(t *testing.T) { + testData := []struct { + name string + header string + want string + }{{ + name: "sum has two carries", + header: "4540005800000000ff11ffff0aeb1d070aed8877", + want: "fffe", + }, { + name: "wikipedia case", + header: "45000073000040004011b861c0a80001c0a800c7", + want: "b861", + }} + + for _, test := range testData { + bytes, err := hex.DecodeString(test.header) + if err != nil { + t.Fatalf("Failed to Decode header: %v", err) + } + wantBytes, err := hex.DecodeString(test.want) + if err != nil { + t.Fatalf("Failed to decode want checksum: %v", err) + } + + if got, want := checksum(bytes), binary.BigEndian.Uint16(wantBytes); got != want { + t.Errorf("In test %q, got incorrect checksum: got(%x), want(%x)", test.name, got, want) + } + } +} diff --git a/vendor/github.com/google/gopacket/layers/ip6.go b/vendor/github.com/google/gopacket/layers/ip6.go new file mode 100644 index 0000000..b5befe9 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/ip6.go @@ -0,0 +1,650 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// Copyright 2009-2011 Andreas Krennmair. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "errors" + "fmt" + "net" + + "github.com/google/gopacket" +) + +const ( + IPv6HopByHopOptionJumbogram = 0xC2 // RFC 2675 +) + +const ( + ipv6MaxPayloadLength = 65535 +) + +// IPv6 is the layer for the IPv6 header. +type IPv6 struct { + // http://www.networksorcery.com/enp/protocol/ipv6.htm + BaseLayer + Version uint8 + TrafficClass uint8 + FlowLabel uint32 + Length uint16 + NextHeader IPProtocol + HopLimit uint8 + SrcIP net.IP + DstIP net.IP + HopByHop *IPv6HopByHop + // hbh will be pointed to by HopByHop if that layer exists. + hbh IPv6HopByHop +} + +// LayerType returns LayerTypeIPv6 +func (i *IPv6) LayerType() gopacket.LayerType { return LayerTypeIPv6 } + +func (i *IPv6) NetworkFlow() gopacket.Flow { + return gopacket.NewFlow(EndpointIPv6, i.SrcIP, i.DstIP) +} + +// Search for Jumbo Payload TLV in IPv6HopByHop and return (length, true) if found +func getIPv6HopByHopJumboLength(hopopts *IPv6HopByHop) (uint32, bool, error) { + var tlv *IPv6HopByHopOption + + for _, t := range hopopts.Options { + if t.OptionType == IPv6HopByHopOptionJumbogram { + tlv = t + break + } + } + if tlv == nil { + // Not found + return 0, false, nil + } + if len(tlv.OptionData) != 4 { + return 0, false, errors.New("Jumbo length TLV data must have length 4") + } + l := binary.BigEndian.Uint32(tlv.OptionData) + if l <= ipv6MaxPayloadLength { + return 0, false, fmt.Errorf("Jumbo length cannot be less than %d", ipv6MaxPayloadLength+1) + } + // Found + return l, true, nil +} + +// Adds zero-valued Jumbo TLV to IPv6 header if it does not exist +// (if necessary add hop-by-hop header) +func addIPv6JumboOption(ip6 *IPv6) { + var tlv *IPv6HopByHopOption + + if ip6.HopByHop == nil { + // Add IPv6 HopByHop + ip6.HopByHop = &IPv6HopByHop{} + ip6.HopByHop.NextHeader = ip6.NextHeader + ip6.HopByHop.HeaderLength = 0 + ip6.NextHeader = IPProtocolIPv6HopByHop + } + for _, t := range ip6.HopByHop.Options { + if t.OptionType == IPv6HopByHopOptionJumbogram { + tlv = t + break + } + } + if tlv == nil { + // Add Jumbo TLV + tlv = &IPv6HopByHopOption{} + ip6.HopByHop.Options = append(ip6.HopByHop.Options, tlv) + } + tlv.SetJumboLength(0) +} + +// Set jumbo length in serialized IPv6 payload (starting with HopByHop header) +func setIPv6PayloadJumboLength(hbh []byte) error { + pLen := len(hbh) + if pLen < 8 { + //HopByHop is minimum 8 bytes + return fmt.Errorf("Invalid IPv6 payload (length %d)", pLen) + } + hbhLen := int((hbh[1] + 1) * 8) + if hbhLen > pLen { + return fmt.Errorf("Invalid hop-by-hop length (length: %d, payload: %d", hbhLen, pLen) + } + offset := 2 //start with options + for offset < hbhLen { + opt := hbh[offset] + if opt == 0 { + //Pad1 + offset += 1 + continue + } + optLen := int(hbh[offset+1]) + if opt == IPv6HopByHopOptionJumbogram { + if optLen == 4 { + binary.BigEndian.PutUint32(hbh[offset+2:], uint32(pLen)) + return nil + } + return fmt.Errorf("Jumbo TLV too short (%d bytes)", optLen) + } + offset += 2 + optLen + } + return errors.New("Jumbo TLV not found") +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (ip6 *IPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + var jumbo bool + var err error + + payload := b.Bytes() + pLen := len(payload) + if pLen > ipv6MaxPayloadLength { + jumbo = true + if opts.FixLengths { + // We need to set the length later because the hop-by-hop header may + // not exist or else need padding, so pLen may yet change + addIPv6JumboOption(ip6) + } else if ip6.HopByHop == nil { + return fmt.Errorf("Cannot fit payload length of %d into IPv6 packet", pLen) + } else { + _, ok, err := getIPv6HopByHopJumboLength(ip6.HopByHop) + if err != nil { + return err + } + if !ok { + return errors.New("Missing jumbo length hop-by-hop option") + } + } + } + if ip6.HopByHop != nil { + if ip6.NextHeader != IPProtocolIPv6HopByHop { + // Just fix it instead of throwing an error + ip6.NextHeader = IPProtocolIPv6HopByHop + } + err = ip6.HopByHop.SerializeTo(b, opts) + if err != nil { + return err + } + payload = b.Bytes() + pLen = len(payload) + if opts.FixLengths && jumbo { + err := setIPv6PayloadJumboLength(payload) + if err != nil { + return err + } + } + } + if !jumbo && pLen > ipv6MaxPayloadLength { + return errors.New("Cannot fit payload into IPv6 header") + } + bytes, err := b.PrependBytes(40) + if err != nil { + return err + } + bytes[0] = (ip6.Version << 4) | (ip6.TrafficClass >> 4) + bytes[1] = (ip6.TrafficClass << 4) | uint8(ip6.FlowLabel>>16) + binary.BigEndian.PutUint16(bytes[2:], uint16(ip6.FlowLabel)) + if opts.FixLengths { + if jumbo { + ip6.Length = 0 + } else { + ip6.Length = uint16(pLen) + } + } + binary.BigEndian.PutUint16(bytes[4:], ip6.Length) + bytes[6] = byte(ip6.NextHeader) + bytes[7] = byte(ip6.HopLimit) + if err := ip6.AddressTo16(); err != nil { + return err + } + copy(bytes[8:], ip6.SrcIP) + copy(bytes[24:], ip6.DstIP) + return nil +} + +func (ip6 *IPv6) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + ip6.Version = uint8(data[0]) >> 4 + ip6.TrafficClass = uint8((binary.BigEndian.Uint16(data[0:2]) >> 4) & 0x00FF) + ip6.FlowLabel = binary.BigEndian.Uint32(data[0:4]) & 0x000FFFFF + ip6.Length = binary.BigEndian.Uint16(data[4:6]) + ip6.NextHeader = IPProtocol(data[6]) + ip6.HopLimit = data[7] + ip6.SrcIP = data[8:24] + ip6.DstIP = data[24:40] + ip6.HopByHop = nil + ip6.BaseLayer = BaseLayer{data[:40], data[40:]} + + // We treat a HopByHop IPv6 option as part of the IPv6 packet, since its + // options are crucial for understanding what's actually happening per packet. + if ip6.NextHeader == IPProtocolIPv6HopByHop { + err := ip6.hbh.DecodeFromBytes(ip6.Payload, df) + if err != nil { + return err + } + ip6.HopByHop = &ip6.hbh + pEnd, jumbo, err := getIPv6HopByHopJumboLength(ip6.HopByHop) + if err != nil { + return err + } + if jumbo && ip6.Length == 0 { + pEnd := int(pEnd) + if pEnd > len(ip6.Payload) { + df.SetTruncated() + pEnd = len(ip6.Payload) + } + ip6.Payload = ip6.Payload[:pEnd] + return nil + } else if jumbo && ip6.Length != 0 { + return errors.New("IPv6 has jumbo length and IPv6 length is not 0") + } else if !jumbo && ip6.Length == 0 { + return errors.New("IPv6 length 0, but HopByHop header does not have jumbogram option") + } + } + + if ip6.Length == 0 { + return fmt.Errorf("IPv6 length 0, but next header is %v, not HopByHop", ip6.NextHeader) + } else { + pEnd := int(ip6.Length) + if pEnd > len(ip6.Payload) { + df.SetTruncated() + pEnd = len(ip6.Payload) + } + ip6.Payload = ip6.Payload[:pEnd] + } + return nil +} + +func (i *IPv6) CanDecode() gopacket.LayerClass { + return LayerTypeIPv6 +} + +func (i *IPv6) NextLayerType() gopacket.LayerType { + if i.HopByHop != nil { + return i.HopByHop.NextHeader.LayerType() + } + return i.NextHeader.LayerType() +} + +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 { + p.AddLayer(ip6.HopByHop) + } + if err != nil { + return err + } + return p.NextDecoder(ip6.NextLayerType()) +} + +type ipv6HeaderTLVOption struct { + OptionType, OptionLength uint8 + ActualLength int + OptionData []byte + OptionAlignment [2]uint8 // Xn+Y = [2]uint8{X, Y} +} + +func (h *ipv6HeaderTLVOption) serializeTo(data []byte, fixLengths bool, dryrun bool) int { + if fixLengths { + h.OptionLength = uint8(len(h.OptionData)) + } + length := int(h.OptionLength) + 2 + if !dryrun { + data[0] = h.OptionType + data[1] = h.OptionLength + copy(data[2:], h.OptionData) + } + return length +} + +func decodeIPv6HeaderTLVOption(data []byte) (h *ipv6HeaderTLVOption) { + h = &ipv6HeaderTLVOption{} + if data[0] == 0 { + h.ActualLength = 1 + return + } + h.OptionType = data[0] + h.OptionLength = data[1] + h.ActualLength = int(h.OptionLength) + 2 + h.OptionData = data[2:h.ActualLength] + return +} + +func serializeTLVOptionPadding(data []byte, padLength int) { + if padLength <= 0 { + return + } + if padLength == 1 { + data[0] = 0x0 + return + } + tlvLength := uint8(padLength) - 2 + data[0] = 0x1 + data[1] = tlvLength + if tlvLength != 0 { + for k := range data[2:] { + data[k+2] = 0x0 + } + } + return +} + +// If buf is 'nil' do a serialize dry run +func serializeIPv6HeaderTLVOptions(buf []byte, options []*ipv6HeaderTLVOption, fixLengths bool) int { + var l int + + dryrun := buf == nil + length := 2 + for _, opt := range options { + if fixLengths { + x := int(opt.OptionAlignment[0]) + y := int(opt.OptionAlignment[1]) + if x != 0 { + n := length / x + offset := x*n + y + if offset < length { + offset += x + } + if length != offset { + pad := offset - length + if !dryrun { + serializeTLVOptionPadding(buf[length-2:], pad) + } + length += pad + } + } + } + if dryrun { + l = opt.serializeTo(nil, fixLengths, true) + } else { + l = opt.serializeTo(buf[length-2:], fixLengths, false) + } + length += l + } + if fixLengths { + pad := length % 8 + if pad != 0 { + if !dryrun { + serializeTLVOptionPadding(buf[length-2:], pad) + } + length += pad + } + } + return length - 2 +} + +type ipv6ExtensionBase struct { + BaseLayer + NextHeader IPProtocol + HeaderLength uint8 + ActualLength int +} + +func decodeIPv6ExtensionBase(data []byte) (i ipv6ExtensionBase) { + i.NextHeader = IPProtocol(data[0]) + i.HeaderLength = data[1] + i.ActualLength = int(i.HeaderLength)*8 + 8 + i.Contents = data[:i.ActualLength] + i.Payload = data[i.ActualLength:] + return +} + +// IPv6ExtensionSkipper is a DecodingLayer which decodes and ignores v6 +// extensions. You can use it with a DecodingLayerParser to handle IPv6 stacks +// which may or may not have extensions. +type IPv6ExtensionSkipper struct { + NextHeader IPProtocol + BaseLayer +} + +func (i *IPv6ExtensionSkipper) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + extension := decodeIPv6ExtensionBase(data) + i.BaseLayer = BaseLayer{data[:extension.ActualLength], data[extension.ActualLength:]} + i.NextHeader = extension.NextHeader + return nil +} + +func (i *IPv6ExtensionSkipper) CanDecode() gopacket.LayerClass { + return LayerClassIPv6Extension +} + +func (i *IPv6ExtensionSkipper) NextLayerType() gopacket.LayerType { + return i.NextHeader.LayerType() +} + +// IPv6HopByHopOption is a TLV option present in an IPv6 hop-by-hop extension. +type IPv6HopByHopOption ipv6HeaderTLVOption + +// IPv6HopByHop is the IPv6 hop-by-hop extension. +type IPv6HopByHop struct { + ipv6ExtensionBase + Options []*IPv6HopByHopOption +} + +// LayerType returns LayerTypeIPv6HopByHop. +func (i *IPv6HopByHop) LayerType() gopacket.LayerType { return LayerTypeIPv6HopByHop } + +func (i *IPv6HopByHop) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + var bytes []byte + var err error + + o := make([]*ipv6HeaderTLVOption, 0, len(i.Options)) + for _, v := range i.Options { + o = append(o, (*ipv6HeaderTLVOption)(v)) + } + + l := serializeIPv6HeaderTLVOptions(nil, o, opts.FixLengths) + bytes, err = b.PrependBytes(l) + if err != nil { + return err + } + serializeIPv6HeaderTLVOptions(bytes, o, opts.FixLengths) + + length := len(bytes) + 2 + if length%8 != 0 { + return errors.New("IPv6HopByHop actual length must be multiple of 8") + } + bytes, err = b.PrependBytes(2) + if err != nil { + return err + } + bytes[0] = uint8(i.NextHeader) + if opts.FixLengths { + i.HeaderLength = uint8((length / 8) - 1) + } + bytes[1] = uint8(i.HeaderLength) + return nil +} + +func (i *IPv6HopByHop) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + i.ipv6ExtensionBase = decodeIPv6ExtensionBase(data) + offset := 2 + for offset < i.ActualLength { + opt := decodeIPv6HeaderTLVOption(data[offset:]) + i.Options = append(i.Options, (*IPv6HopByHopOption)(opt)) + offset += opt.ActualLength + } + return nil +} + +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 (o *IPv6HopByHopOption) SetJumboLength(len uint32) { + o.OptionType = IPv6HopByHopOptionJumbogram + o.OptionLength = 4 + o.ActualLength = 6 + if o.OptionData == nil { + o.OptionData = make([]byte, 4) + } + binary.BigEndian.PutUint32(o.OptionData, len) + o.OptionAlignment = [2]uint8{4, 2} +} + +// IPv6Routing is the IPv6 routing extension. +type IPv6Routing struct { + ipv6ExtensionBase + RoutingType uint8 + SegmentsLeft uint8 + // This segment is supposed to be zero according to RFC2460, the second set of + // 4 bytes in the extension. + Reserved []byte + // SourceRoutingIPs is the set of IPv6 addresses requested for source routing, + // set only if RoutingType == 0. + SourceRoutingIPs []net.IP +} + +// LayerType returns LayerTypeIPv6Routing. +func (i *IPv6Routing) LayerType() gopacket.LayerType { return LayerTypeIPv6Routing } + +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 (i.ActualLength-8)%16 != 0 { + return fmt.Errorf("Invalid IPv6 source routing, length of type 0 packet %d", i.ActualLength) + } + for d := i.Contents[8:]; len(d) >= 16; d = d[16:] { + i.SourceRoutingIPs = append(i.SourceRoutingIPs, net.IP(d[:16])) + } + default: + return fmt.Errorf("Unknown IPv6 routing header type %d", i.RoutingType) + } + p.AddLayer(i) + return p.NextDecoder(i.NextHeader) +} + +// IPv6Fragment is the IPv6 fragment header, used for packet +// fragmentation/defragmentation. +type IPv6Fragment struct { + BaseLayer + NextHeader IPProtocol + // Reserved1 is bits [8-16), from least to most significant, 0-indexed + Reserved1 uint8 + FragmentOffset uint16 + // Reserved2 is bits [29-31), from least to most significant, 0-indexed + Reserved2 uint8 + MoreFragments bool + Identification uint32 +} + +// LayerType returns LayerTypeIPv6Fragment. +func (i *IPv6Fragment) LayerType() gopacket.LayerType { return LayerTypeIPv6Fragment } + +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) +} + +// IPv6DestinationOption is a TLV option present in an IPv6 destination options extension. +type IPv6DestinationOption ipv6HeaderTLVOption + +// IPv6Destination is the IPv6 destination options header. +type IPv6Destination struct { + ipv6ExtensionBase + Options []*IPv6DestinationOption +} + +// LayerType returns LayerTypeIPv6Destination. +func (i *IPv6Destination) LayerType() gopacket.LayerType { return LayerTypeIPv6Destination } + +func (i *IPv6Destination) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + i.ipv6ExtensionBase = decodeIPv6ExtensionBase(data) + offset := 2 + for offset < i.ActualLength { + opt := decodeIPv6HeaderTLVOption(data[offset:]) + i.Options = append(i.Options, (*IPv6DestinationOption)(opt)) + offset += opt.ActualLength + } + return nil +} + +func decodeIPv6Destination(data []byte, p gopacket.PacketBuilder) error { + i := &IPv6Destination{} + err := i.DecodeFromBytes(data, p) + p.AddLayer(i) + if err != nil { + return err + } + return p.NextDecoder(i.NextHeader) +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (i *IPv6Destination) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + var bytes []byte + var err error + + o := make([]*ipv6HeaderTLVOption, 0, len(i.Options)) + for _, v := range i.Options { + o = append(o, (*ipv6HeaderTLVOption)(v)) + } + + l := serializeIPv6HeaderTLVOptions(nil, o, opts.FixLengths) + bytes, err = b.PrependBytes(l) + if err != nil { + return err + } + serializeIPv6HeaderTLVOptions(bytes, o, opts.FixLengths) + + length := len(bytes) + 2 + if length%8 != 0 { + return errors.New("IPv6Destination actual length must be multiple of 8") + } + bytes, err = b.PrependBytes(2) + if err != nil { + return err + } + bytes[0] = uint8(i.NextHeader) + if opts.FixLengths { + i.HeaderLength = uint8((length / 8) - 1) + } + bytes[1] = uint8(i.HeaderLength) + return nil +} + +func checkIPv6Address(addr net.IP) error { + if len(addr) == net.IPv6len { + return nil + } + if len(addr) == net.IPv4len { + return errors.New("address is IPv4") + } + return fmt.Errorf("wrong length of %d bytes instead of %d", len(addr), net.IPv6len) +} + +func (ip *IPv6) AddressTo16() error { + if err := checkIPv6Address(ip.SrcIP); err != nil { + return fmt.Errorf("Invalid source IPv6 address (%s)", err) + } + if err := checkIPv6Address(ip.DstIP); err != nil { + return fmt.Errorf("Invalid destination IPv6 address (%s)", err) + } + return nil +} diff --git a/vendor/github.com/google/gopacket/layers/ip6_test.go b/vendor/github.com/google/gopacket/layers/ip6_test.go new file mode 100644 index 0000000..ab22f17 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/ip6_test.go @@ -0,0 +1,430 @@ +// Copyright 2014, Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "bytes" + "github.com/google/gopacket" + "net" + "reflect" + "testing" +) + +func TestSerializeIPv6HeaderTLVOptions(t *testing.T) { + //RFC 2460 Appendix B + /* + Example 3 + + A Hop-by-Hop or Destination Options header containing both options X + and Y from Examples 1 and 2 would have one of the two following + formats, depending on which option appeared first: + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Next Header | Hdr Ext Len=3 | Option Type=X |Opt Data Len=12| + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | 4-octet field | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + + 8-octet field + + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | PadN Option=1 |Opt Data Len=1 | 0 | Option Type=Y | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |Opt Data Len=7 | 1-octet field | 2-octet field | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | 4-octet field | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | PadN Option=1 |Opt Data Len=2 | 0 | 0 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + opt1 := &ipv6HeaderTLVOption{} + opt1.OptionType = 0x1e + opt1.OptionData = []byte{0xaa, 0xaa, 0xaa, 0xaa, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb} + opt1.OptionAlignment = [2]uint8{8, 2} + + opt2 := &ipv6HeaderTLVOption{} + opt2.OptionType = 0x3e + opt2.OptionData = []byte{0x11, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44} + opt2.OptionAlignment = [2]uint8{4, 3} + + l := serializeIPv6HeaderTLVOptions(nil, []*ipv6HeaderTLVOption{opt1, opt2}, true) + b := make([]byte, l) + serializeIPv6HeaderTLVOptions(b, []*ipv6HeaderTLVOption{opt1, opt2}, true) + got := b + want := []byte{0x1e, 0x0c, 0xaa, 0xaa, 0xaa, 0xaa, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x01, 0x01, 0x00, 0x3e, 0x07, 0x11, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x01, 0x02, 0x00, 0x00} + + if !bytes.Equal(got, want) { + t.Errorf("IPv6HeaderTLVOption serialize (X,Y) failed:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want) + } + + /* + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Next Header | Hdr Ext Len=3 | Pad1 Option=0 | Option Type=Y | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |Opt Data Len=7 | 1-octet field | 2-octet field | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | 4-octet field | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | PadN Option=1 |Opt Data Len=4 | 0 | 0 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | 0 | 0 | Option Type=X |Opt Data Len=12| + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | 4-octet field | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + + 8-octet field + + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + + l = serializeIPv6HeaderTLVOptions(nil, []*ipv6HeaderTLVOption{opt2, opt1}, true) + b = make([]byte, l) + serializeIPv6HeaderTLVOptions(b, []*ipv6HeaderTLVOption{opt2, opt1}, true) + got = b + want = []byte{0x00, 0x3e, 0x07, 0x11, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, 0xaa, 0xaa, 0xaa, 0xaa, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb} + + if !bytes.Equal(got, want) { + t.Errorf("IPv6HeaderTLVOption serialize (Y,X) failed:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want) + } +} + +var testPacketIPv6HopByHop0 = []byte{ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x3b, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, +} + +func TestPacketIPv6HopByHop0Serialize(t *testing.T) { + var serialize []gopacket.SerializableLayer = make([]gopacket.SerializableLayer, 0, 2) + var err error + + ip6 := &IPv6{} + ip6.Version = 6 + ip6.NextHeader = IPProtocolIPv6HopByHop + ip6.HopLimit = 64 + ip6.SrcIP = net.ParseIP("2001:db8::1") + ip6.DstIP = net.ParseIP("2001:db8::2") + serialize = append(serialize, ip6) + + tlv := &IPv6HopByHopOption{} + tlv.OptionType = 0x01 //PadN + tlv.OptionData = []byte{0x00, 0x00, 0x00, 0x00} + hop := &IPv6HopByHop{} + hop.Options = append(hop.Options, tlv) + hop.NextHeader = IPProtocolNoNextHeader + ip6.HopByHop = hop + + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{FixLengths: true} + err = gopacket.SerializeLayers(buf, opts, serialize...) + if err != nil { + t.Fatal(err) + } + + got := buf.Bytes() + want := testPacketIPv6HopByHop0 + if !bytes.Equal(got, want) { + t.Errorf("IPv6HopByHop serialize failed:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want) + } +} + +func TestPacketIPv6HopByHop0Decode(t *testing.T) { + ip6 := &IPv6{ + BaseLayer: BaseLayer{ + Contents: []byte{ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + }, + Payload: []byte{0x3b, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00}, + }, + Version: 6, + TrafficClass: 0, + FlowLabel: 0, + Length: 8, + NextHeader: IPProtocolIPv6HopByHop, + HopLimit: 64, + SrcIP: net.IP{0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + DstIP: net.IP{0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + } + + hop := &ip6.hbh + hop.ipv6ExtensionBase = ipv6ExtensionBase{ + BaseLayer: BaseLayer{ + Contents: []byte{0x3b, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00}, + Payload: []byte{}, + }, + NextHeader: IPProtocolNoNextHeader, + HeaderLength: uint8(0), + ActualLength: 8, + } + opt := &IPv6HopByHopOption{ + OptionType: uint8(0x01), + OptionLength: uint8(0x04), + ActualLength: 6, + OptionData: []byte{0x00, 0x00, 0x00, 0x00}, + } + hop.Options = append(hop.Options, opt) + ip6.HopByHop = hop + + p := gopacket.NewPacket(testPacketIPv6HopByHop0, LinkTypeRaw, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeIPv6, LayerTypeIPv6HopByHop}, t) + if got, ok := p.Layer(LayerTypeIPv6).(*IPv6); ok { + want := ip6 + want.HopByHop = got.HopByHop // avoid comparing pointers + if !reflect.DeepEqual(got, want) { + t.Errorf("IPv6 packet processing failed:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want) + } + } else { + t.Error("No IPv6 layer type found in packet") + } + if got, ok := p.Layer(LayerTypeIPv6HopByHop).(*IPv6HopByHop); ok { + want := hop + if !reflect.DeepEqual(got, want) { + t.Errorf("IPv6HopByHop packet processing failed:\ngot\n%#v\n\nwant:\n%#v\n\n", got, want) + } + } else { + t.Error("No IPv6HopByHop layer type found in packet") + } +} + +// testPacketIPv6Destination0 is the packet: +// 12:40:14.429409595 IP6 2001:db8::1 > 2001:db8::2: DSTOPT no next header +// 0x0000: 6000 0000 0008 3c40 2001 0db8 0000 0000 `.....<@........ +// 0x0010: 0000 0000 0000 0001 2001 0db8 0000 0000 ................ +// 0x0020: 0000 0000 0000 0002 3b00 0104 0000 0000 ........;....... +var testPacketIPv6Destination0 = []byte{ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3c, 0x40, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x3b, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, +} + +func TestPacketIPv6Destination0Serialize(t *testing.T) { + var serialize []gopacket.SerializableLayer = make([]gopacket.SerializableLayer, 0, 2) + var err error + + ip6 := &IPv6{} + ip6.Version = 6 + ip6.NextHeader = IPProtocolIPv6Destination + ip6.HopLimit = 64 + ip6.SrcIP = net.ParseIP("2001:db8::1") + ip6.DstIP = net.ParseIP("2001:db8::2") + serialize = append(serialize, ip6) + + tlv := &IPv6DestinationOption{} + tlv.OptionType = 0x01 //PadN + tlv.OptionData = []byte{0x00, 0x00, 0x00, 0x00} + dst := &IPv6Destination{} + dst.Options = append(dst.Options, tlv) + dst.NextHeader = IPProtocolNoNextHeader + serialize = append(serialize, dst) + + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{FixLengths: true} + err = gopacket.SerializeLayers(buf, opts, serialize...) + if err != nil { + t.Fatal(err) + } + + got := buf.Bytes() + want := testPacketIPv6Destination0 + if !bytes.Equal(got, want) { + t.Errorf("IPv6Destination serialize failed:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want) + } +} + +func TestPacketIPv6Destination0Decode(t *testing.T) { + ip6 := &IPv6{ + BaseLayer: BaseLayer{ + Contents: []byte{ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3c, 0x40, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + }, + Payload: []byte{0x3b, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00}, + }, + Version: 6, + TrafficClass: 0, + FlowLabel: 0, + Length: 8, + NextHeader: IPProtocolIPv6Destination, + HopLimit: 64, + SrcIP: net.IP{0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + DstIP: net.IP{0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + } + + dst := &IPv6Destination{} + dst.BaseLayer = BaseLayer{ + Contents: []byte{0x3b, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00}, + Payload: []byte{}, + } + dst.NextHeader = IPProtocolNoNextHeader + dst.HeaderLength = uint8(0) + dst.ActualLength = 8 + opt := &IPv6DestinationOption{ + OptionType: uint8(0x01), + OptionLength: uint8(0x04), + ActualLength: 6, + OptionData: []byte{0x00, 0x00, 0x00, 0x00}, + } + dst.Options = append(dst.Options, opt) + + p := gopacket.NewPacket(testPacketIPv6Destination0, LinkTypeRaw, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeIPv6, LayerTypeIPv6Destination}, t) + if got, ok := p.Layer(LayerTypeIPv6).(*IPv6); ok { + want := ip6 + if !reflect.DeepEqual(got, want) { + t.Errorf("IPv6 packet processing failed:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want) + } + } else { + t.Error("No IPv6 layer type found in packet") + } + if got, ok := p.Layer(LayerTypeIPv6Destination).(*IPv6Destination); ok { + want := dst + if !reflect.DeepEqual(got, want) { + t.Errorf("IPv6Destination packet processing failed:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want) + } + } else { + t.Error("No IPv6Destination layer type found in packet") + } +} + +var testPacketIPv6JumbogramHeader = []byte{ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x3b, 0x00, 0xc2, 0x04, 0x00, 0x01, 0x00, 0x08, +} + +func TestIPv6JumbogramSerialize(t *testing.T) { + var serialize []gopacket.SerializableLayer = make([]gopacket.SerializableLayer, 0, 2) + var err error + + ip6 := &IPv6{} + ip6.Version = 6 + ip6.NextHeader = IPProtocolNoNextHeader + ip6.HopLimit = 64 + ip6.SrcIP = net.ParseIP("2001:db8::1") + ip6.DstIP = net.ParseIP("2001:db8::2") + serialize = append(serialize, ip6) + + payload := make([]byte, ipv6MaxPayloadLength+1) + for i := range payload { + payload[i] = 0xfe + } + serialize = append(serialize, gopacket.Payload(payload)) + + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{FixLengths: true} + err = gopacket.SerializeLayers(buf, opts, serialize...) + if err != nil { + t.Fatal(err) + } + + got := buf.Bytes() + w := new(bytes.Buffer) + w.Write(testPacketIPv6JumbogramHeader) + w.Write(payload) + want := w.Bytes() + + if !bytes.Equal(got, want) { + t.Errorf("IPv6 Jumbogram serialize failed:\ngot:\n%v\n\nwant:\n%v\n\n", + gopacket.LongBytesGoString(got), gopacket.LongBytesGoString(want)) + } +} + +func TestIPv6JumbogramDecode(t *testing.T) { + payload := make([]byte, ipv6MaxPayloadLength+1) + for i := range payload { + payload[i] = 0xfe + } + + ip6 := &IPv6{ + BaseLayer: BaseLayer{ + Contents: []byte{ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + }, + }, + Version: 6, + TrafficClass: 0, + FlowLabel: 0, + Length: 0, + NextHeader: IPProtocolIPv6HopByHop, + HopLimit: 64, + SrcIP: net.IP{0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + DstIP: net.IP{0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + } + buf := new(bytes.Buffer) + buf.Write([]byte{0x3b, 0x00, 0xc2, 0x04, 0x00, 0x01, 0x00, 0x08}) + buf.Write(payload) + ip6.Payload = buf.Bytes() + + hop := &ip6.hbh + hop.Contents = []byte{0x3b, 0x00, 0xc2, 0x04, 0x00, 0x01, 0x00, 0x08} + hop.Payload = payload + hop.NextHeader = IPProtocolNoNextHeader + hop.HeaderLength = uint8(0) + hop.ActualLength = 8 + opt := &IPv6HopByHopOption{} + opt.OptionType = uint8(0xc2) + opt.OptionLength = uint8(0x04) + opt.ActualLength = 6 + opt.OptionData = []byte{0x00, 0x01, 0x00, 0x08} + hop.Options = append(hop.Options, opt) + ip6.HopByHop = hop + + pkt := new(bytes.Buffer) + pkt.Write(testPacketIPv6JumbogramHeader) + pkt.Write(payload) + + p := gopacket.NewPacket(pkt.Bytes(), LinkTypeRaw, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeIPv6, LayerTypeIPv6HopByHop, gopacket.LayerTypePayload}, t) + + if got, ok := p.Layer(LayerTypeIPv6).(*IPv6); ok { + want := ip6 + want.HopByHop = got.HopByHop // Hack, avoid comparing pointers + if !reflect.DeepEqual(got, want) { + t.Errorf("IPv6 packet processing failed:\ngot:\n%v\n\nwant:\n%v\n\n", + gopacket.LayerGoString(got), gopacket.LayerGoString(want)) + } + } else { + t.Error("No IPv6 layer type found in packet") + } + + if got, ok := p.Layer(LayerTypeIPv6HopByHop).(*IPv6HopByHop); ok { + want := hop + if !reflect.DeepEqual(got, want) { + t.Errorf("IPv6HopByHop packet processing failed:\ngot:\n%v\n\nwant:\n%v\n\n", + gopacket.LayerGoString(got), gopacket.LayerGoString(want)) + } + } else { + t.Error("No IPv6HopByHop layer type found in packet") + } + + if got, ok := p.Layer(gopacket.LayerTypePayload).(*gopacket.Payload); ok { + want := (*gopacket.Payload)(&payload) + if !reflect.DeepEqual(got, want) { + t.Errorf("Payload packet processing failed:\ngot:\n%v\n\nwant:\n%v\n\n", + gopacket.LayerGoString(got), gopacket.LayerGoString(want)) + } + } else { + t.Error("No Payload layer type found in packet") + } +} diff --git a/vendor/github.com/google/gopacket/layers/ipsec.go b/vendor/github.com/google/gopacket/layers/ipsec.go new file mode 100644 index 0000000..19163fa --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/ipsec.go @@ -0,0 +1,68 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "github.com/google/gopacket" +) + +// IPSecAH is the authentication header for IPv4/6 defined in +// http://tools.ietf.org/html/rfc2402 +type IPSecAH struct { + // While the auth header can be used for both IPv4 and v6, its format is that of + // an IPv6 extension (NextHeader, PayloadLength, etc...), so we use ipv6ExtensionBase + // to build it. + ipv6ExtensionBase + Reserved uint16 + SPI, Seq uint32 + AuthenticationData []byte +} + +// LayerType returns LayerTypeIPSecAH. +func (i *IPSecAH) LayerType() gopacket.LayerType { return LayerTypeIPSecAH } + +func decodeIPSecAH(data []byte, p gopacket.PacketBuilder) error { + i := &IPSecAH{ + ipv6ExtensionBase: ipv6ExtensionBase{ + NextHeader: IPProtocol(data[0]), + HeaderLength: data[1], + }, + Reserved: binary.BigEndian.Uint16(data[2:4]), + SPI: binary.BigEndian.Uint32(data[4:8]), + Seq: binary.BigEndian.Uint32(data[8:12]), + } + i.ActualLength = (int(i.HeaderLength) + 2) * 4 + i.AuthenticationData = data[12:i.ActualLength] + i.Contents = data[:i.ActualLength] + i.Payload = data[i.ActualLength:] + p.AddLayer(i) + return p.NextDecoder(i.NextHeader) +} + +// IPSecESP is the encapsulating security payload defined in +// http://tools.ietf.org/html/rfc2406 +type IPSecESP struct { + BaseLayer + SPI, Seq uint32 + // Encrypted contains the encrypted set of bytes sent in an ESP + Encrypted []byte +} + +// LayerType returns LayerTypeIPSecESP. +func (i *IPSecESP) LayerType() gopacket.LayerType { return LayerTypeIPSecESP } + +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 +} diff --git a/vendor/github.com/google/gopacket/layers/ipsec_test.go b/vendor/github.com/google/gopacket/layers/ipsec_test.go new file mode 100644 index 0000000..466646d --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/ipsec_test.go @@ -0,0 +1,154 @@ +// Copyright 2012, Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "github.com/google/gopacket" + "reflect" + "testing" +) + +// testPacketIPSecAHTransport is the packet: +// 20:45:10.325850 IP 192.168.1.1 > 192.168.1.2: AH(spi=0x00000101,seq=0x1): ICMP echo request, id 1560, seq 1, length 64 +// 0x0000: 7ec0 ffc6 48f1 1a0e 3c4e 3b3a 0800 4500 ~...H...<N;:..E. +// 0x0010: 006c 650a 4000 4033 5201 c0a8 0101 c0a8 .le.@.@3R....... +// 0x0020: 0102 0104 0000 0000 0101 0000 0001 2533 ..............%3 +// 0x0030: 01b1 a20b b6f1 bdbf 9d9e 0800 fbe5 0618 ................ +// 0x0040: 0001 c6e1 a354 0000 0000 c8f7 0400 0000 .....T.......... +// 0x0050: 0000 1011 1213 1415 1617 1819 1a1b 1c1d ................ +// 0x0060: 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d ...!"#$%&'()*+,- +// 0x0070: 2e2f 3031 3233 3435 3637 ./01234567 +var testPacketIPSecAHTransport = []byte{ + 0x7e, 0xc0, 0xff, 0xc6, 0x48, 0xf1, 0x1a, 0x0e, 0x3c, 0x4e, 0x3b, 0x3a, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x6c, 0x65, 0x0a, 0x40, 0x00, 0x40, 0x33, 0x52, 0x01, 0xc0, 0xa8, 0x01, 0x01, 0xc0, 0xa8, + 0x01, 0x02, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x25, 0x33, + 0x01, 0xb1, 0xa2, 0x0b, 0xb6, 0xf1, 0xbd, 0xbf, 0x9d, 0x9e, 0x08, 0x00, 0xfb, 0xe5, 0x06, 0x18, + 0x00, 0x01, 0xc6, 0xe1, 0xa3, 0x54, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xf7, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, +} + +func TestPacketIPSecAHTransport(t *testing.T) { + p := gopacket.NewPacket(testPacketIPSecAHTransport, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeIPSecAH, LayerTypeICMPv4, gopacket.LayerTypePayload}, t) + if got, ok := p.Layer(LayerTypeIPSecAH).(*IPSecAH); ok { + want := &IPSecAH{ + Reserved: 0x0, + SPI: 0x101, + Seq: 1, + AuthenticationData: []byte{0x25, 0x33, 0x01, 0xb1, 0xa2, 0x0b, 0xb6, 0xf1, 0xbd, 0xbf, 0x9d, 0x9e}, + } + want.BaseLayer = BaseLayer{testPacketIPSecAHTransport[34:58], testPacketIPSecAHTransport[58:]} + want.NextHeader = IPProtocolICMPv4 + want.HeaderLength = 0x4 + want.ActualLength = 0x18 + if !reflect.DeepEqual(want, got) { + t.Errorf("IPSecAH layer mismatch, \nwant %#v\ngot %#v\n", want, got) + } + } +} + +func BenchmarkDecodePacketIPSecAHTransport(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketIPSecAHTransport, LinkTypeEthernet, gopacket.NoCopy) + } +} + +// testPacketIPSecAHTunnel is the packet: +// 14:45:43.252917 IP 192.168.1.1 > 192.168.1.2: AH(spi=0x00000101,seq=0x1): IP 172.16.1.1 > 172.16.2.1: ICMP echo request, id 31322, seq 1, length 64 (ipip-proto-4) +// 0x0000: 7220 4d91 63c9 566c ed2d 73cd 0800 4500 r.M.c.Vl.-s...E. +// 0x0010: 0080 0000 4000 4033 b6f7 c0a8 0101 c0a8 ....@.@3........ +// 0x0020: 0102 0404 0000 0000 0101 0000 0001 cca4 ................ +// 0x0030: 01da 9eb4 fb75 10fe 5a59 4500 0054 a96f .....u..ZYE..T.o +// 0x0040: 4000 4001 3617 ac10 0101 ac10 0201 0800 @.@.6........... +// 0x0050: d75f 7a5a 0001 0741 3355 0000 0000 a9db ._zZ...A3U...... +// 0x0060: 0300 0000 0000 1011 1213 1415 1617 1819 ................ +// 0x0070: 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 .......!"#$%&'() +// 0x0080: 2a2b 2c2d 2e2f 3031 3233 3435 3637 *+,-./01234567 +var testPacketIPSecAHTunnel = []byte{ + 0x72, 0x20, 0x4d, 0x91, 0x63, 0xc9, 0x56, 0x6c, 0xed, 0x2d, 0x73, 0xcd, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x40, 0x33, 0xb6, 0xf7, 0xc0, 0xa8, 0x01, 0x01, 0xc0, 0xa8, + 0x01, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0xcc, 0xa4, + 0x01, 0xda, 0x9e, 0xb4, 0xfb, 0x75, 0x10, 0xfe, 0x5a, 0x59, 0x45, 0x00, 0x00, 0x54, 0xa9, 0x6f, + 0x40, 0x00, 0x40, 0x01, 0x36, 0x17, 0xac, 0x10, 0x01, 0x01, 0xac, 0x10, 0x02, 0x01, 0x08, 0x00, + 0xd7, 0x5f, 0x7a, 0x5a, 0x00, 0x01, 0x07, 0x41, 0x33, 0x55, 0x00, 0x00, 0x00, 0x00, 0xa9, 0xdb, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, +} + +func TestPacketIPSecAHTunnel(t *testing.T) { + p := gopacket.NewPacket(testPacketIPSecAHTunnel, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeIPSecAH, LayerTypeIPv4, LayerTypeICMPv4, gopacket.LayerTypePayload}, t) + if got, ok := p.Layer(LayerTypeIPSecAH).(*IPSecAH); ok { + want := &IPSecAH{ + Reserved: 0x0, + SPI: 0x101, + Seq: 1, + AuthenticationData: []byte{0xcc, 0xa4, 0x01, 0xda, 0x9e, 0xb4, 0xfb, 0x75, 0x10, 0xfe, 0x5a, 0x59}, + } + want.BaseLayer = BaseLayer{testPacketIPSecAHTunnel[34:58], testPacketIPSecAHTunnel[58:]} + want.NextHeader = IPProtocolIPv4 + want.HeaderLength = 0x4 + want.ActualLength = 0x18 + if !reflect.DeepEqual(want, got) { + t.Errorf("IPSecAH layer mismatch, \nwant %#v\ngot %#v\n", want, got) + } + } +} + +func BenchmarkDecodePacketIPSecAHTunnel(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketIPSecAHTunnel, LinkTypeEthernet, gopacket.NoCopy) + } +} + +// testPacketIPSecESP is the packet: +// 04:30:37.629376 IP 190.0.0.1 > 190.0.0.2: ESP(spi=0x0000006e,seq=0x13), length 116 +// 0x0000: 0000 0000 0012 0011 434a d70a 0800 4500 ........CJ....E. +// 0x0010: 0088 0000 4000 4032 be40 be00 0001 be00 ....@.@2.@...... +// 0x0020: 0002 0000 006e 0000 0013 82f4 1077 0418 .....n.......w.. +// 0x0030: e8ce dc45 1bac 22bb daaf 2ad2 c2e8 315b ...E.."...*...1[ +// 0x0040: ce9a 39da 2aae cf43 3716 70ab 7e7c 4676 ..9.*..C7.p.~|Fv +// 0x0050: c3fc d109 c990 274d f81c 6534 9a40 a0ef ......'M..e4.@.. +// 0x0060: 46b1 7da5 05af dda8 d0ba 6e23 d1ee 1f10 F.}.......n#.... +// 0x0070: 730c 7371 03b1 445c 2f70 852f 8475 12fb s.sq..D\/p./.u.. +// 0x0080: b057 a19b a617 bae7 09ca 8836 942f 3334 .W.........6./34 +// 0x0090: 312b 96d2 a4e3 1+.... +var testPacketIPSecESP = []byte{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x11, 0x43, 0x4a, 0xd7, 0x0a, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x88, 0x00, 0x00, 0x40, 0x00, 0x40, 0x32, 0xbe, 0x40, 0xbe, 0x00, 0x00, 0x01, 0xbe, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x13, 0x82, 0xf4, 0x10, 0x77, 0x04, 0x18, + 0xe8, 0xce, 0xdc, 0x45, 0x1b, 0xac, 0x22, 0xbb, 0xda, 0xaf, 0x2a, 0xd2, 0xc2, 0xe8, 0x31, 0x5b, + 0xce, 0x9a, 0x39, 0xda, 0x2a, 0xae, 0xcf, 0x43, 0x37, 0x16, 0x70, 0xab, 0x7e, 0x7c, 0x46, 0x76, + 0xc3, 0xfc, 0xd1, 0x09, 0xc9, 0x90, 0x27, 0x4d, 0xf8, 0x1c, 0x65, 0x34, 0x9a, 0x40, 0xa0, 0xef, + 0x46, 0xb1, 0x7d, 0xa5, 0x05, 0xaf, 0xdd, 0xa8, 0xd0, 0xba, 0x6e, 0x23, 0xd1, 0xee, 0x1f, 0x10, + 0x73, 0x0c, 0x73, 0x71, 0x03, 0xb1, 0x44, 0x5c, 0x2f, 0x70, 0x85, 0x2f, 0x84, 0x75, 0x12, 0xfb, + 0xb0, 0x57, 0xa1, 0x9b, 0xa6, 0x17, 0xba, 0xe7, 0x09, 0xca, 0x88, 0x36, 0x94, 0x2f, 0x33, 0x34, + 0x31, 0x2b, 0x96, 0xd2, 0xa4, 0xe3, +} + +func TestPacketIPSecESP(t *testing.T) { + p := gopacket.NewPacket(testPacketIPSecESP, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeIPSecESP}, t) +} + +func BenchmarkDecodePacketIPSecESP(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketIPSecESP, LinkTypeEthernet, gopacket.NoCopy) + } +} diff --git a/vendor/github.com/google/gopacket/layers/layertypes.go b/vendor/github.com/google/gopacket/layers/layertypes.go new file mode 100644 index 0000000..faffb91 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/layertypes.go @@ -0,0 +1,177 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "github.com/google/gopacket" +) + +var ( + LayerTypeARP = gopacket.RegisterLayerType(10, gopacket.LayerTypeMetadata{Name: "ARP", Decoder: gopacket.DecodeFunc(decodeARP)}) + LayerTypeCiscoDiscovery = gopacket.RegisterLayerType(11, gopacket.LayerTypeMetadata{Name: "CiscoDiscovery", Decoder: gopacket.DecodeFunc(decodeCiscoDiscovery)}) + LayerTypeEthernetCTP = gopacket.RegisterLayerType(12, gopacket.LayerTypeMetadata{Name: "EthernetCTP", Decoder: gopacket.DecodeFunc(decodeEthernetCTP)}) + LayerTypeEthernetCTPForwardData = gopacket.RegisterLayerType(13, gopacket.LayerTypeMetadata{Name: "EthernetCTPForwardData", Decoder: nil}) + LayerTypeEthernetCTPReply = gopacket.RegisterLayerType(14, gopacket.LayerTypeMetadata{Name: "EthernetCTPReply", Decoder: nil}) + LayerTypeDot1Q = gopacket.RegisterLayerType(15, gopacket.LayerTypeMetadata{Name: "Dot1Q", Decoder: gopacket.DecodeFunc(decodeDot1Q)}) + LayerTypeEtherIP = gopacket.RegisterLayerType(16, gopacket.LayerTypeMetadata{Name: "EtherIP", Decoder: gopacket.DecodeFunc(decodeEtherIP)}) + LayerTypeEthernet = gopacket.RegisterLayerType(17, gopacket.LayerTypeMetadata{Name: "Ethernet", Decoder: gopacket.DecodeFunc(decodeEthernet)}) + LayerTypeGRE = gopacket.RegisterLayerType(18, gopacket.LayerTypeMetadata{Name: "GRE", Decoder: gopacket.DecodeFunc(decodeGRE)}) + LayerTypeICMPv4 = gopacket.RegisterLayerType(19, gopacket.LayerTypeMetadata{Name: "ICMPv4", Decoder: gopacket.DecodeFunc(decodeICMPv4)}) + LayerTypeIPv4 = gopacket.RegisterLayerType(20, gopacket.LayerTypeMetadata{Name: "IPv4", Decoder: gopacket.DecodeFunc(decodeIPv4)}) + LayerTypeIPv6 = gopacket.RegisterLayerType(21, gopacket.LayerTypeMetadata{Name: "IPv6", Decoder: gopacket.DecodeFunc(decodeIPv6)}) + LayerTypeLLC = gopacket.RegisterLayerType(22, gopacket.LayerTypeMetadata{Name: "LLC", Decoder: gopacket.DecodeFunc(decodeLLC)}) + LayerTypeSNAP = gopacket.RegisterLayerType(23, gopacket.LayerTypeMetadata{Name: "SNAP", Decoder: gopacket.DecodeFunc(decodeSNAP)}) + LayerTypeMPLS = gopacket.RegisterLayerType(24, gopacket.LayerTypeMetadata{Name: "MPLS", Decoder: gopacket.DecodeFunc(decodeMPLS)}) + LayerTypePPP = gopacket.RegisterLayerType(25, gopacket.LayerTypeMetadata{Name: "PPP", Decoder: gopacket.DecodeFunc(decodePPP)}) + LayerTypePPPoE = gopacket.RegisterLayerType(26, gopacket.LayerTypeMetadata{Name: "PPPoE", Decoder: gopacket.DecodeFunc(decodePPPoE)}) + LayerTypeRUDP = gopacket.RegisterLayerType(27, gopacket.LayerTypeMetadata{Name: "RUDP", Decoder: gopacket.DecodeFunc(decodeRUDP)}) + LayerTypeSCTP = gopacket.RegisterLayerType(28, gopacket.LayerTypeMetadata{Name: "SCTP", Decoder: gopacket.DecodeFunc(decodeSCTP)}) + LayerTypeSCTPUnknownChunkType = gopacket.RegisterLayerType(29, gopacket.LayerTypeMetadata{Name: "SCTPUnknownChunkType", Decoder: nil}) + LayerTypeSCTPData = gopacket.RegisterLayerType(30, gopacket.LayerTypeMetadata{Name: "SCTPData", Decoder: nil}) + LayerTypeSCTPInit = gopacket.RegisterLayerType(31, gopacket.LayerTypeMetadata{Name: "SCTPInit", Decoder: nil}) + LayerTypeSCTPSack = gopacket.RegisterLayerType(32, gopacket.LayerTypeMetadata{Name: "SCTPSack", Decoder: nil}) + LayerTypeSCTPHeartbeat = gopacket.RegisterLayerType(33, gopacket.LayerTypeMetadata{Name: "SCTPHeartbeat", Decoder: nil}) + LayerTypeSCTPError = gopacket.RegisterLayerType(34, gopacket.LayerTypeMetadata{Name: "SCTPError", Decoder: nil}) + LayerTypeSCTPShutdown = gopacket.RegisterLayerType(35, gopacket.LayerTypeMetadata{Name: "SCTPShutdown", Decoder: nil}) + LayerTypeSCTPShutdownAck = gopacket.RegisterLayerType(36, gopacket.LayerTypeMetadata{Name: "SCTPShutdownAck", Decoder: nil}) + LayerTypeSCTPCookieEcho = gopacket.RegisterLayerType(37, gopacket.LayerTypeMetadata{Name: "SCTPCookieEcho", Decoder: nil}) + LayerTypeSCTPEmptyLayer = gopacket.RegisterLayerType(38, gopacket.LayerTypeMetadata{Name: "SCTPEmptyLayer", Decoder: nil}) + LayerTypeSCTPInitAck = gopacket.RegisterLayerType(39, gopacket.LayerTypeMetadata{Name: "SCTPInitAck", Decoder: nil}) + LayerTypeSCTPHeartbeatAck = gopacket.RegisterLayerType(40, gopacket.LayerTypeMetadata{Name: "SCTPHeartbeatAck", Decoder: nil}) + LayerTypeSCTPAbort = gopacket.RegisterLayerType(41, gopacket.LayerTypeMetadata{Name: "SCTPAbort", Decoder: nil}) + LayerTypeSCTPShutdownComplete = gopacket.RegisterLayerType(42, gopacket.LayerTypeMetadata{Name: "SCTPShutdownComplete", Decoder: nil}) + LayerTypeSCTPCookieAck = gopacket.RegisterLayerType(43, gopacket.LayerTypeMetadata{Name: "SCTPCookieAck", Decoder: nil}) + LayerTypeTCP = gopacket.RegisterLayerType(44, gopacket.LayerTypeMetadata{Name: "TCP", Decoder: gopacket.DecodeFunc(decodeTCP)}) + LayerTypeUDP = gopacket.RegisterLayerType(45, gopacket.LayerTypeMetadata{Name: "UDP", Decoder: gopacket.DecodeFunc(decodeUDP)}) + LayerTypeIPv6HopByHop = gopacket.RegisterLayerType(46, gopacket.LayerTypeMetadata{Name: "IPv6HopByHop", Decoder: gopacket.DecodeFunc(decodeIPv6HopByHop)}) + LayerTypeIPv6Routing = gopacket.RegisterLayerType(47, gopacket.LayerTypeMetadata{Name: "IPv6Routing", Decoder: gopacket.DecodeFunc(decodeIPv6Routing)}) + LayerTypeIPv6Fragment = gopacket.RegisterLayerType(48, gopacket.LayerTypeMetadata{Name: "IPv6Fragment", Decoder: gopacket.DecodeFunc(decodeIPv6Fragment)}) + LayerTypeIPv6Destination = gopacket.RegisterLayerType(49, gopacket.LayerTypeMetadata{Name: "IPv6Destination", Decoder: gopacket.DecodeFunc(decodeIPv6Destination)}) + LayerTypeIPSecAH = gopacket.RegisterLayerType(50, gopacket.LayerTypeMetadata{Name: "IPSecAH", Decoder: gopacket.DecodeFunc(decodeIPSecAH)}) + LayerTypeIPSecESP = gopacket.RegisterLayerType(51, gopacket.LayerTypeMetadata{Name: "IPSecESP", Decoder: gopacket.DecodeFunc(decodeIPSecESP)}) + LayerTypeUDPLite = gopacket.RegisterLayerType(52, gopacket.LayerTypeMetadata{Name: "UDPLite", Decoder: gopacket.DecodeFunc(decodeUDPLite)}) + LayerTypeFDDI = gopacket.RegisterLayerType(53, gopacket.LayerTypeMetadata{Name: "FDDI", Decoder: gopacket.DecodeFunc(decodeFDDI)}) + LayerTypeLoopback = gopacket.RegisterLayerType(54, gopacket.LayerTypeMetadata{Name: "Loopback", Decoder: gopacket.DecodeFunc(decodeLoopback)}) + LayerTypeEAP = gopacket.RegisterLayerType(55, gopacket.LayerTypeMetadata{Name: "EAP", Decoder: gopacket.DecodeFunc(decodeEAP)}) + LayerTypeEAPOL = gopacket.RegisterLayerType(56, gopacket.LayerTypeMetadata{Name: "EAPOL", Decoder: gopacket.DecodeFunc(decodeEAPOL)}) + LayerTypeICMPv6 = gopacket.RegisterLayerType(57, gopacket.LayerTypeMetadata{Name: "ICMPv6", Decoder: gopacket.DecodeFunc(decodeICMPv6)}) + LayerTypeLinkLayerDiscovery = gopacket.RegisterLayerType(58, gopacket.LayerTypeMetadata{Name: "LinkLayerDiscovery", Decoder: gopacket.DecodeFunc(decodeLinkLayerDiscovery)}) + LayerTypeCiscoDiscoveryInfo = gopacket.RegisterLayerType(59, gopacket.LayerTypeMetadata{Name: "CiscoDiscoveryInfo", Decoder: gopacket.DecodeFunc(decodeCiscoDiscoveryInfo)}) + LayerTypeLinkLayerDiscoveryInfo = gopacket.RegisterLayerType(60, gopacket.LayerTypeMetadata{Name: "LinkLayerDiscoveryInfo", Decoder: nil}) + LayerTypeNortelDiscovery = gopacket.RegisterLayerType(61, gopacket.LayerTypeMetadata{Name: "NortelDiscovery", Decoder: gopacket.DecodeFunc(decodeNortelDiscovery)}) + LayerTypeIGMP = gopacket.RegisterLayerType(62, gopacket.LayerTypeMetadata{Name: "IGMP", Decoder: gopacket.DecodeFunc(decodeIGMP)}) + LayerTypePFLog = gopacket.RegisterLayerType(63, gopacket.LayerTypeMetadata{Name: "PFLog", Decoder: gopacket.DecodeFunc(decodePFLog)}) + LayerTypeRadioTap = gopacket.RegisterLayerType(64, gopacket.LayerTypeMetadata{Name: "RadioTap", Decoder: gopacket.DecodeFunc(decodeRadioTap)}) + LayerTypeDot11 = gopacket.RegisterLayerType(65, gopacket.LayerTypeMetadata{Name: "Dot11", Decoder: gopacket.DecodeFunc(decodeDot11)}) + LayerTypeDot11Ctrl = gopacket.RegisterLayerType(66, gopacket.LayerTypeMetadata{Name: "Dot11Ctrl", Decoder: gopacket.DecodeFunc(decodeDot11Ctrl)}) + LayerTypeDot11Data = gopacket.RegisterLayerType(67, gopacket.LayerTypeMetadata{Name: "Dot11Data", Decoder: gopacket.DecodeFunc(decodeDot11Data)}) + LayerTypeDot11DataCFAck = gopacket.RegisterLayerType(68, gopacket.LayerTypeMetadata{Name: "Dot11DataCFAck", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAck)}) + LayerTypeDot11DataCFPoll = gopacket.RegisterLayerType(69, gopacket.LayerTypeMetadata{Name: "Dot11DataCFPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataCFPoll)}) + LayerTypeDot11DataCFAckPoll = gopacket.RegisterLayerType(70, gopacket.LayerTypeMetadata{Name: "Dot11DataCFAckPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAckPoll)}) + LayerTypeDot11DataNull = gopacket.RegisterLayerType(71, gopacket.LayerTypeMetadata{Name: "Dot11DataNull", Decoder: gopacket.DecodeFunc(decodeDot11DataNull)}) + LayerTypeDot11DataCFAckNoData = gopacket.RegisterLayerType(72, gopacket.LayerTypeMetadata{Name: "Dot11DataCFAck", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAck)}) + LayerTypeDot11DataCFPollNoData = gopacket.RegisterLayerType(73, gopacket.LayerTypeMetadata{Name: "Dot11DataCFPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataCFPoll)}) + LayerTypeDot11DataCFAckPollNoData = gopacket.RegisterLayerType(74, gopacket.LayerTypeMetadata{Name: "Dot11DataCFAckPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAckPoll)}) + LayerTypeDot11DataQOSData = gopacket.RegisterLayerType(75, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSData", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSData)}) + LayerTypeDot11DataQOSDataCFAck = gopacket.RegisterLayerType(76, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSDataCFAck", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSDataCFAck)}) + LayerTypeDot11DataQOSDataCFPoll = gopacket.RegisterLayerType(77, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSDataCFPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSDataCFPoll)}) + LayerTypeDot11DataQOSDataCFAckPoll = gopacket.RegisterLayerType(78, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSDataCFAckPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSDataCFAckPoll)}) + LayerTypeDot11DataQOSNull = gopacket.RegisterLayerType(79, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSNull", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSNull)}) + LayerTypeDot11DataQOSCFPollNoData = gopacket.RegisterLayerType(80, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSCFPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSCFPollNoData)}) + LayerTypeDot11DataQOSCFAckPollNoData = gopacket.RegisterLayerType(81, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSCFAckPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSCFAckPollNoData)}) + LayerTypeDot11InformationElement = gopacket.RegisterLayerType(82, gopacket.LayerTypeMetadata{Name: "Dot11InformationElement", Decoder: gopacket.DecodeFunc(decodeDot11InformationElement)}) + LayerTypeDot11CtrlCTS = gopacket.RegisterLayerType(83, gopacket.LayerTypeMetadata{Name: "Dot11CtrlCTS", Decoder: gopacket.DecodeFunc(decodeDot11CtrlCTS)}) + LayerTypeDot11CtrlRTS = gopacket.RegisterLayerType(84, gopacket.LayerTypeMetadata{Name: "Dot11CtrlRTS", Decoder: gopacket.DecodeFunc(decodeDot11CtrlRTS)}) + LayerTypeDot11CtrlBlockAckReq = gopacket.RegisterLayerType(85, gopacket.LayerTypeMetadata{Name: "Dot11CtrlBlockAckReq", Decoder: gopacket.DecodeFunc(decodeDot11CtrlBlockAckReq)}) + LayerTypeDot11CtrlBlockAck = gopacket.RegisterLayerType(86, gopacket.LayerTypeMetadata{Name: "Dot11CtrlBlockAck", Decoder: gopacket.DecodeFunc(decodeDot11CtrlBlockAck)}) + LayerTypeDot11CtrlPowersavePoll = gopacket.RegisterLayerType(87, gopacket.LayerTypeMetadata{Name: "Dot11CtrlPowersavePoll", Decoder: gopacket.DecodeFunc(decodeDot11CtrlPowersavePoll)}) + LayerTypeDot11CtrlAck = gopacket.RegisterLayerType(88, gopacket.LayerTypeMetadata{Name: "Dot11CtrlAck", Decoder: gopacket.DecodeFunc(decodeDot11CtrlAck)}) + LayerTypeDot11CtrlCFEnd = gopacket.RegisterLayerType(89, gopacket.LayerTypeMetadata{Name: "Dot11CtrlCFEnd", Decoder: gopacket.DecodeFunc(decodeDot11CtrlCFEnd)}) + LayerTypeDot11CtrlCFEndAck = gopacket.RegisterLayerType(90, gopacket.LayerTypeMetadata{Name: "Dot11CtrlCFEndAck", Decoder: gopacket.DecodeFunc(decodeDot11CtrlCFEndAck)}) + LayerTypeDot11MgmtAssociationReq = gopacket.RegisterLayerType(91, gopacket.LayerTypeMetadata{Name: "Dot11MgmtAssociationReq", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAssociationReq)}) + LayerTypeDot11MgmtAssociationResp = gopacket.RegisterLayerType(92, gopacket.LayerTypeMetadata{Name: "Dot11MgmtAssociationResp", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAssociationResp)}) + LayerTypeDot11MgmtReassociationReq = gopacket.RegisterLayerType(93, gopacket.LayerTypeMetadata{Name: "Dot11MgmtReassociationReq", Decoder: gopacket.DecodeFunc(decodeDot11MgmtReassociationReq)}) + LayerTypeDot11MgmtReassociationResp = gopacket.RegisterLayerType(94, gopacket.LayerTypeMetadata{Name: "Dot11MgmtReassociationResp", Decoder: gopacket.DecodeFunc(decodeDot11MgmtReassociationResp)}) + LayerTypeDot11MgmtProbeReq = gopacket.RegisterLayerType(95, gopacket.LayerTypeMetadata{Name: "Dot11MgmtProbeReq", Decoder: gopacket.DecodeFunc(decodeDot11MgmtProbeReq)}) + LayerTypeDot11MgmtProbeResp = gopacket.RegisterLayerType(96, gopacket.LayerTypeMetadata{Name: "Dot11MgmtProbeResp", Decoder: gopacket.DecodeFunc(decodeDot11MgmtProbeResp)}) + LayerTypeDot11MgmtMeasurementPilot = gopacket.RegisterLayerType(97, gopacket.LayerTypeMetadata{Name: "Dot11MgmtMeasurementPilot", Decoder: gopacket.DecodeFunc(decodeDot11MgmtMeasurementPilot)}) + LayerTypeDot11MgmtBeacon = gopacket.RegisterLayerType(98, gopacket.LayerTypeMetadata{Name: "Dot11MgmtBeacon", Decoder: gopacket.DecodeFunc(decodeDot11MgmtBeacon)}) + LayerTypeDot11MgmtATIM = gopacket.RegisterLayerType(99, gopacket.LayerTypeMetadata{Name: "Dot11MgmtATIM", Decoder: gopacket.DecodeFunc(decodeDot11MgmtATIM)}) + LayerTypeDot11MgmtDisassociation = gopacket.RegisterLayerType(100, gopacket.LayerTypeMetadata{Name: "Dot11MgmtDisassociation", Decoder: gopacket.DecodeFunc(decodeDot11MgmtDisassociation)}) + LayerTypeDot11MgmtAuthentication = gopacket.RegisterLayerType(101, gopacket.LayerTypeMetadata{Name: "Dot11MgmtAuthentication", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAuthentication)}) + LayerTypeDot11MgmtDeauthentication = gopacket.RegisterLayerType(102, gopacket.LayerTypeMetadata{Name: "Dot11MgmtDeauthentication", Decoder: gopacket.DecodeFunc(decodeDot11MgmtDeauthentication)}) + LayerTypeDot11MgmtAction = gopacket.RegisterLayerType(103, gopacket.LayerTypeMetadata{Name: "Dot11MgmtAction", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAction)}) + LayerTypeDot11MgmtActionNoAck = gopacket.RegisterLayerType(104, gopacket.LayerTypeMetadata{Name: "Dot11MgmtActionNoAck", Decoder: gopacket.DecodeFunc(decodeDot11MgmtActionNoAck)}) + LayerTypeDot11MgmtArubaWLAN = gopacket.RegisterLayerType(105, gopacket.LayerTypeMetadata{Name: "Dot11MgmtArubaWLAN", Decoder: gopacket.DecodeFunc(decodeDot11MgmtArubaWLAN)}) + LayerTypeDot11WEP = gopacket.RegisterLayerType(106, gopacket.LayerTypeMetadata{Name: "Dot11WEP", Decoder: gopacket.DecodeFunc(decodeDot11WEP)}) + LayerTypeDNS = gopacket.RegisterLayerType(107, gopacket.LayerTypeMetadata{Name: "DNS", Decoder: gopacket.DecodeFunc(decodeDNS)}) + LayerTypeUSB = gopacket.RegisterLayerType(108, gopacket.LayerTypeMetadata{Name: "USB", Decoder: gopacket.DecodeFunc(decodeUSB)}) + LayerTypeUSBRequestBlockSetup = gopacket.RegisterLayerType(109, gopacket.LayerTypeMetadata{Name: "USBRequestBlockSetup", Decoder: gopacket.DecodeFunc(decodeUSBRequestBlockSetup)}) + LayerTypeUSBControl = gopacket.RegisterLayerType(110, gopacket.LayerTypeMetadata{Name: "USBControl", Decoder: gopacket.DecodeFunc(decodeUSBControl)}) + LayerTypeUSBInterrupt = gopacket.RegisterLayerType(111, gopacket.LayerTypeMetadata{Name: "USBInterrupt", Decoder: gopacket.DecodeFunc(decodeUSBInterrupt)}) + LayerTypeUSBBulk = gopacket.RegisterLayerType(112, gopacket.LayerTypeMetadata{Name: "USBBulk", Decoder: gopacket.DecodeFunc(decodeUSBBulk)}) + LayerTypeLinuxSLL = gopacket.RegisterLayerType(113, gopacket.LayerTypeMetadata{Name: "Linux SLL", Decoder: gopacket.DecodeFunc(decodeLinuxSLL)}) + LayerTypeSFlow = gopacket.RegisterLayerType(114, gopacket.LayerTypeMetadata{Name: "SFlow", Decoder: gopacket.DecodeFunc(decodeSFlow)}) + LayerTypePrismHeader = gopacket.RegisterLayerType(115, gopacket.LayerTypeMetadata{Name: "Prism monitor mode header", Decoder: gopacket.DecodeFunc(decodePrismHeader)}) + LayerTypeVXLAN = gopacket.RegisterLayerType(116, gopacket.LayerTypeMetadata{Name: "VXLAN", Decoder: gopacket.DecodeFunc(decodeVXLAN)}) + LayerTypeNTP = gopacket.RegisterLayerType(117, gopacket.LayerTypeMetadata{Name: "NTP", Decoder: gopacket.DecodeFunc(decodeNTP)}) + LayerTypeDHCPv4 = gopacket.RegisterLayerType(118, gopacket.LayerTypeMetadata{Name: "DHCPv4", Decoder: gopacket.DecodeFunc(decodeDHCPv4)}) + LayerTypeVRRP = gopacket.RegisterLayerType(119, gopacket.LayerTypeMetadata{Name: "VRRP", Decoder: gopacket.DecodeFunc(decodeVRRP)}) + LayerTypeGeneve = gopacket.RegisterLayerType(120, gopacket.LayerTypeMetadata{Name: "Geneve", Decoder: gopacket.DecodeFunc(decodeGeneve)}) + LayerTypeSTP = gopacket.RegisterLayerType(121, gopacket.LayerTypeMetadata{Name: "STP", Decoder: gopacket.DecodeFunc(decodeSTP)}) + LayerTypeBFD = gopacket.RegisterLayerType(122, gopacket.LayerTypeMetadata{Name: "BFD", Decoder: gopacket.DecodeFunc(decodeBFD)}) + LayerTypeOSPF = gopacket.RegisterLayerType(123, gopacket.LayerTypeMetadata{Name: "OSPF", Decoder: gopacket.DecodeFunc(decodeOSPF)}) +) + +var ( + // LayerClassIPNetwork contains TCP/IP network layer types. + LayerClassIPNetwork = gopacket.NewLayerClass([]gopacket.LayerType{ + LayerTypeIPv4, + LayerTypeIPv6, + }) + // LayerClassIPTransport contains TCP/IP transport layer types. + LayerClassIPTransport = gopacket.NewLayerClass([]gopacket.LayerType{ + LayerTypeTCP, + LayerTypeUDP, + LayerTypeSCTP, + }) + // LayerClassIPControl contains TCP/IP control protocols. + LayerClassIPControl = gopacket.NewLayerClass([]gopacket.LayerType{ + LayerTypeICMPv4, + LayerTypeICMPv6, + }) + // LayerClassSCTPChunk contains SCTP chunk types (not the top-level SCTP + // layer). + LayerClassSCTPChunk = gopacket.NewLayerClass([]gopacket.LayerType{ + LayerTypeSCTPUnknownChunkType, + LayerTypeSCTPData, + LayerTypeSCTPInit, + LayerTypeSCTPSack, + LayerTypeSCTPHeartbeat, + LayerTypeSCTPError, + LayerTypeSCTPShutdown, + LayerTypeSCTPShutdownAck, + LayerTypeSCTPCookieEcho, + LayerTypeSCTPEmptyLayer, + LayerTypeSCTPInitAck, + LayerTypeSCTPHeartbeatAck, + LayerTypeSCTPAbort, + LayerTypeSCTPShutdownComplete, + LayerTypeSCTPCookieAck, + }) + // LayerClassIPv6Extension contains IPv6 extension headers. + LayerClassIPv6Extension = gopacket.NewLayerClass([]gopacket.LayerType{ + LayerTypeIPv6HopByHop, + LayerTypeIPv6Routing, + LayerTypeIPv6Fragment, + LayerTypeIPv6Destination, + }) + LayerClassIPSec = gopacket.NewLayerClass([]gopacket.LayerType{ + LayerTypeIPSecAH, + LayerTypeIPSecESP, + }) +) diff --git a/vendor/github.com/google/gopacket/layers/linux_sll.go b/vendor/github.com/google/gopacket/layers/linux_sll.go new file mode 100644 index 0000000..b186053 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/linux_sll.go @@ -0,0 +1,96 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "errors" + "fmt" + "net" + + "github.com/google/gopacket" +) + +type LinuxSLLPacketType uint16 + +const ( + LinuxSLLPacketTypeHost LinuxSLLPacketType = 0 // To us + LinuxSLLPacketTypeBroadcast LinuxSLLPacketType = 1 // To all + LinuxSLLPacketTypeMulticast LinuxSLLPacketType = 2 // To group + LinuxSLLPacketTypeOtherhost LinuxSLLPacketType = 3 // To someone else + LinuxSLLPacketTypeOutgoing LinuxSLLPacketType = 4 // Outgoing of any type + // These ones are invisible by user level + LinuxSLLPacketTypeLoopback LinuxSLLPacketType = 5 // MC/BRD frame looped back + LinuxSLLPacketTypeFastroute LinuxSLLPacketType = 6 // Fastrouted frame +) + +func (l LinuxSLLPacketType) String() string { + switch l { + case LinuxSLLPacketTypeHost: + return "host" + case LinuxSLLPacketTypeBroadcast: + return "broadcast" + case LinuxSLLPacketTypeMulticast: + return "multicast" + case LinuxSLLPacketTypeOtherhost: + return "otherhost" + case LinuxSLLPacketTypeOutgoing: + return "outgoing" + case LinuxSLLPacketTypeLoopback: + return "loopback" + case LinuxSLLPacketTypeFastroute: + return "fastroute" + } + return fmt.Sprintf("Unknown(%d)", int(l)) +} + +type LinuxSLL struct { + BaseLayer + PacketType LinuxSLLPacketType + AddrLen uint16 + Addr net.HardwareAddr + EthernetType EthernetType +} + +// LayerType returns LayerTypeLinuxSLL. +func (sll *LinuxSLL) LayerType() gopacket.LayerType { return LayerTypeLinuxSLL } + +func (sll *LinuxSLL) CanDecode() gopacket.LayerClass { + return LayerTypeLinuxSLL +} + +func (sll *LinuxSLL) LinkFlow() gopacket.Flow { + return gopacket.NewFlow(EndpointMAC, sll.Addr, nil) +} + +func (sll *LinuxSLL) NextLayerType() gopacket.LayerType { + return sll.EthernetType.LayerType() +} + +func (sll *LinuxSLL) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 16 { + return errors.New("Linux SLL packet too small") + } + sll.PacketType = LinuxSLLPacketType(binary.BigEndian.Uint16(data[0:2])) + sll.AddrLen = binary.BigEndian.Uint16(data[4:6]) + + sll.Addr = net.HardwareAddr(data[6 : sll.AddrLen+6]) + sll.EthernetType = EthernetType(binary.BigEndian.Uint16(data[14:16])) + sll.BaseLayer = BaseLayer{data[:16], data[16:]} + + return nil +} + +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) +} diff --git a/vendor/github.com/google/gopacket/layers/llc.go b/vendor/github.com/google/gopacket/layers/llc.go new file mode 100644 index 0000000..59453fe --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/llc.go @@ -0,0 +1,146 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "errors" + + "github.com/google/gopacket" +) + +// LLC is the layer used for 802.2 Logical Link Control headers. +// See http://standards.ieee.org/getieee802/download/802.2-1998.pdf +type LLC struct { + BaseLayer + DSAP uint8 + IG bool // true means group, false means individual + SSAP uint8 + CR bool // true means response, false means command + Control uint16 +} + +// LayerType returns gopacket.LayerTypeLLC. +func (l *LLC) LayerType() gopacket.LayerType { return LayerTypeLLC } + +// SNAP is used inside LLC. See +// http://standards.ieee.org/getieee802/download/802-2001.pdf. +// From http://en.wikipedia.org/wiki/Subnetwork_Access_Protocol: +// "[T]he Subnetwork Access Protocol (SNAP) is a mechanism for multiplexing, +// on networks using IEEE 802.2 LLC, more protocols than can be distinguished +// by the 8-bit 802.2 Service Access Point (SAP) fields." +type SNAP struct { + BaseLayer + OrganizationalCode []byte + Type EthernetType +} + +// LayerType returns gopacket.LayerTypeSNAP. +func (s *SNAP) LayerType() gopacket.LayerType { return LayerTypeSNAP } + +func decodeLLC(data []byte, p gopacket.PacketBuilder) error { + l := &LLC{ + DSAP: data[0] & 0xFE, + IG: data[0]&0x1 != 0, + SSAP: data[1] & 0xFE, + CR: data[1]&0x1 != 0, + Control: uint16(data[2]), + } + if l.Control&0x1 == 0 || l.Control&0x3 == 0x1 { + l.Control = l.Control<<8 | uint16(data[3]) + l.Contents = data[:4] + l.Payload = data[4:] + } else { + l.Contents = data[:3] + l.Payload = data[3:] + } + p.AddLayer(l) + switch { + case l.DSAP == 0xAA && l.SSAP == 0xAA: + return p.NextDecoder(LayerTypeSNAP) + case l.DSAP == 0x42 && l.SSAP == 0x42: + return p.NextDecoder(LayerTypeSTP) + } + return p.NextDecoder(gopacket.DecodeUnknown) +} + +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) +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (l *LLC) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + var ig_flag, cr_flag byte + var length int + + if l.Control&0xFF00 != 0 { + length = 4 + } else { + length = 3 + } + + if l.DSAP&0x1 != 0 { + return errors.New("DSAP value invalid, should not include IG flag bit") + } + + if l.SSAP&0x1 != 0 { + return errors.New("SSAP value invalid, should not include CR flag bit") + } + + if buf, err := b.PrependBytes(length); err != nil { + return err + } else { + ig_flag = 0 + if l.IG { + ig_flag = 0x1 + } + + cr_flag = 0 + if l.CR { + cr_flag = 0x1 + } + + buf[0] = l.DSAP + ig_flag + buf[1] = l.SSAP + cr_flag + + if length == 4 { + buf[2] = uint8(l.Control >> 8) + buf[3] = uint8(l.Control) + } else { + buf[2] = uint8(l.Control) + } + } + + return nil +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (s *SNAP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + if buf, err := b.PrependBytes(5); err != nil { + return err + } else { + buf[0] = s.OrganizationalCode[0] + buf[1] = s.OrganizationalCode[1] + buf[2] = s.OrganizationalCode[2] + binary.BigEndian.PutUint16(buf[3:5], uint16(s.Type)) + } + + return nil +} diff --git a/vendor/github.com/google/gopacket/layers/lldp.go b/vendor/github.com/google/gopacket/layers/lldp.go new file mode 100644 index 0000000..92ec7da --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/lldp.go @@ -0,0 +1,1530 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "errors" + "fmt" + + "github.com/google/gopacket" +) + +// LLDPTLVType is the type of each TLV value in a LinkLayerDiscovery packet. +type LLDPTLVType byte + +const ( + LLDPTLVEnd LLDPTLVType = 0 + LLDPTLVChassisID LLDPTLVType = 1 + LLDPTLVPortID LLDPTLVType = 2 + LLDPTLVTTL LLDPTLVType = 3 + LLDPTLVPortDescription LLDPTLVType = 4 + LLDPTLVSysName LLDPTLVType = 5 + LLDPTLVSysDescription LLDPTLVType = 6 + LLDPTLVSysCapabilities LLDPTLVType = 7 + LLDPTLVMgmtAddress LLDPTLVType = 8 + LLDPTLVOrgSpecific LLDPTLVType = 127 +) + +// LinkLayerDiscoveryValue is a TLV value inside a LinkLayerDiscovery packet layer. +type LinkLayerDiscoveryValue struct { + Type LLDPTLVType + Length uint16 + Value []byte +} + +// LLDPChassisIDSubType specifies the value type for a single LLDPChassisID.ID +type LLDPChassisIDSubType byte + +// LLDP Chassis Types +const ( + LLDPChassisIDSubTypeReserved LLDPChassisIDSubType = 0 + LLDPChassisIDSubTypeChassisComp LLDPChassisIDSubType = 1 + LLDPChassisIDSubtypeIfaceAlias LLDPChassisIDSubType = 2 + LLDPChassisIDSubTypePortComp LLDPChassisIDSubType = 3 + LLDPChassisIDSubTypeMACAddr LLDPChassisIDSubType = 4 + LLDPChassisIDSubTypeNetworkAddr LLDPChassisIDSubType = 5 + LLDPChassisIDSubtypeIfaceName LLDPChassisIDSubType = 6 + LLDPChassisIDSubTypeLocal LLDPChassisIDSubType = 7 +) + +type LLDPChassisID struct { + Subtype LLDPChassisIDSubType + ID []byte +} + +// LLDPPortIDSubType specifies the value type for a single LLDPPortID.ID +type LLDPPortIDSubType byte + +// LLDP PortID types +const ( + LLDPPortIDSubtypeReserved LLDPPortIDSubType = 0 + LLDPPortIDSubtypeIfaceAlias LLDPPortIDSubType = 1 + LLDPPortIDSubtypePortComp LLDPPortIDSubType = 2 + LLDPPortIDSubtypeMACAddr LLDPPortIDSubType = 3 + LLDPPortIDSubtypeNetworkAddr LLDPPortIDSubType = 4 + LLDPPortIDSubtypeIfaceName LLDPPortIDSubType = 5 + LLDPPortIDSubtypeAgentCircuitID LLDPPortIDSubType = 6 + LLDPPortIDSubtypeLocal LLDPPortIDSubType = 7 +) + +type LLDPPortID struct { + Subtype LLDPPortIDSubType + ID []byte +} + +// LinkLayerDiscovery is a packet layer containing the LinkLayer Discovery Protocol. +// See http:http://standards.ieee.org/getieee802/download/802.1AB-2009.pdf +// ChassisID, PortID and TTL are mandatory TLV's. Other values can be decoded +// with DecodeValues() +type LinkLayerDiscovery struct { + BaseLayer + ChassisID LLDPChassisID + PortID LLDPPortID + TTL uint16 + Values []LinkLayerDiscoveryValue +} + +type IEEEOUI uint32 + +// http://standards.ieee.org/develop/regauth/oui/oui.txt +const ( + IEEEOUI8021 IEEEOUI = 0x0080c2 + IEEEOUI8023 IEEEOUI = 0x00120f + IEEEOUI80211 IEEEOUI = 0x000fac + IEEEOUI8021Qbg IEEEOUI = 0x0013BF + IEEEOUICisco2 IEEEOUI = 0x000142 + IEEEOUIMedia IEEEOUI = 0x0012bb // TR-41 + IEEEOUIProfinet IEEEOUI = 0x000ecf + IEEEOUIDCBX IEEEOUI = 0x001b21 +) + +// LLDPOrgSpecificTLV is an Organisation-specific TLV +type LLDPOrgSpecificTLV struct { + OUI IEEEOUI + SubType uint8 + Info []byte +} + +// LLDPCapabilities Types +const ( + LLDPCapsOther uint16 = 1 << 0 + LLDPCapsRepeater uint16 = 1 << 1 + LLDPCapsBridge uint16 = 1 << 2 + LLDPCapsWLANAP uint16 = 1 << 3 + LLDPCapsRouter uint16 = 1 << 4 + LLDPCapsPhone uint16 = 1 << 5 + LLDPCapsDocSis uint16 = 1 << 6 + LLDPCapsStationOnly uint16 = 1 << 7 + LLDPCapsCVLAN uint16 = 1 << 8 + LLDPCapsSVLAN uint16 = 1 << 9 + LLDPCapsTmpr uint16 = 1 << 10 +) + +// LLDPCapabilities represents the capabilities of a device +type LLDPCapabilities struct { + Other bool + Repeater bool + Bridge bool + WLANAP bool + Router bool + Phone bool + DocSis bool + StationOnly bool + CVLAN bool + SVLAN bool + TMPR bool +} + +type LLDPSysCapabilities struct { + SystemCap LLDPCapabilities + EnabledCap LLDPCapabilities +} + +type IANAAddressFamily byte + +// LLDP Management Address Subtypes +// http://www.iana.org/assignments/address-family-numbers/address-family-numbers.xml +const ( + IANAAddressFamilyReserved IANAAddressFamily = 0 + IANAAddressFamilyIPV4 IANAAddressFamily = 1 + IANAAddressFamilyIPV6 IANAAddressFamily = 2 + IANAAddressFamilyNSAP IANAAddressFamily = 3 + IANAAddressFamilyHDLC IANAAddressFamily = 4 + IANAAddressFamilyBBN1822 IANAAddressFamily = 5 + IANAAddressFamily802 IANAAddressFamily = 6 + IANAAddressFamilyE163 IANAAddressFamily = 7 + IANAAddressFamilyE164 IANAAddressFamily = 8 + IANAAddressFamilyF69 IANAAddressFamily = 9 + IANAAddressFamilyX121 IANAAddressFamily = 10 + IANAAddressFamilyIPX IANAAddressFamily = 11 + IANAAddressFamilyAtalk IANAAddressFamily = 12 + IANAAddressFamilyDecnet IANAAddressFamily = 13 + IANAAddressFamilyBanyan IANAAddressFamily = 14 + IANAAddressFamilyE164NSAP IANAAddressFamily = 15 + IANAAddressFamilyDNS IANAAddressFamily = 16 + IANAAddressFamilyDistname IANAAddressFamily = 17 + IANAAddressFamilyASNumber IANAAddressFamily = 18 + IANAAddressFamilyXTPIPV4 IANAAddressFamily = 19 + IANAAddressFamilyXTPIPV6 IANAAddressFamily = 20 + IANAAddressFamilyXTP IANAAddressFamily = 21 + IANAAddressFamilyFcWWPN IANAAddressFamily = 22 + IANAAddressFamilyFcWWNN IANAAddressFamily = 23 + IANAAddressFamilyGWID IANAAddressFamily = 24 + IANAAddressFamilyL2VPN IANAAddressFamily = 25 +) + +type LLDPInterfaceSubtype byte + +// LLDP Interface Subtypes +const ( + LLDPInterfaceSubtypeUnknown LLDPInterfaceSubtype = 1 + LLDPInterfaceSubtypeifIndex LLDPInterfaceSubtype = 2 + LLDPInterfaceSubtypeSysPort LLDPInterfaceSubtype = 3 +) + +type LLDPMgmtAddress struct { + Subtype IANAAddressFamily + Address []byte + InterfaceSubtype LLDPInterfaceSubtype + InterfaceNumber uint32 + OID string +} + +// LinkLayerDiscoveryInfo represents the decoded details for a set of LinkLayerDiscoveryValues +// Organisation-specific TLV's can be decoded using the various Decode() methods +type LinkLayerDiscoveryInfo struct { + BaseLayer + PortDescription string + SysName string + SysDescription string + SysCapabilities LLDPSysCapabilities + MgmtAddress LLDPMgmtAddress + OrgTLVs []LLDPOrgSpecificTLV // Private TLVs + Unknown []LinkLayerDiscoveryValue // undecoded TLVs +} + +/// IEEE 802.1 TLV Subtypes +const ( + LLDP8021SubtypePortVLANID uint8 = 1 + LLDP8021SubtypeProtocolVLANID uint8 = 2 + LLDP8021SubtypeVLANName uint8 = 3 + LLDP8021SubtypeProtocolIdentity uint8 = 4 + LLDP8021SubtypeVDIUsageDigest uint8 = 5 + LLDP8021SubtypeManagementVID uint8 = 6 + LLDP8021SubtypeLinkAggregation uint8 = 7 +) + +// VLAN Port Protocol ID options +const ( + LLDPProtocolVLANIDCapability byte = 1 << 1 + LLDPProtocolVLANIDStatus byte = 1 << 2 +) + +type PortProtocolVLANID struct { + Supported bool + Enabled bool + ID uint16 +} + +type VLANName struct { + ID uint16 + Name string +} + +type ProtocolIdentity []byte + +// LACP options +const ( + LLDPAggregationCapability byte = 1 << 0 + LLDPAggregationStatus byte = 1 << 1 +) + +// IEEE 802 Link Aggregation parameters +type LLDPLinkAggregation struct { + Supported bool + Enabled bool + PortID uint32 +} + +// LLDPInfo8021 represents the information carried in 802.1 Org-specific TLVs +type LLDPInfo8021 struct { + PVID uint16 + PPVIDs []PortProtocolVLANID + VLANNames []VLANName + ProtocolIdentities []ProtocolIdentity + VIDUsageDigest uint32 + ManagementVID uint16 + LinkAggregation LLDPLinkAggregation +} + +// IEEE 802.3 TLV Subtypes +const ( + LLDP8023SubtypeMACPHY uint8 = 1 + LLDP8023SubtypeMDIPower uint8 = 2 + LLDP8023SubtypeLinkAggregation uint8 = 3 + LLDP8023SubtypeMTU uint8 = 4 +) + +// MACPHY options +const ( + LLDPMACPHYCapability byte = 1 << 0 + LLDPMACPHYStatus byte = 1 << 1 +) + +// From IANA-MAU-MIB (introduced by RFC 4836) - dot3MauType +const ( + LLDPMAUTypeUnknown uint16 = 0 + LLDPMAUTypeAUI uint16 = 1 + LLDPMAUType10Base5 uint16 = 2 + LLDPMAUTypeFOIRL uint16 = 3 + LLDPMAUType10Base2 uint16 = 4 + LLDPMAUType10BaseT uint16 = 5 + LLDPMAUType10BaseFP uint16 = 6 + LLDPMAUType10BaseFB uint16 = 7 + LLDPMAUType10BaseFL uint16 = 8 + LLDPMAUType10BROAD36 uint16 = 9 + LLDPMAUType10BaseT_HD uint16 = 10 + LLDPMAUType10BaseT_FD uint16 = 11 + LLDPMAUType10BaseFL_HD uint16 = 12 + LLDPMAUType10BaseFL_FD uint16 = 13 + LLDPMAUType100BaseT4 uint16 = 14 + LLDPMAUType100BaseTX_HD uint16 = 15 + LLDPMAUType100BaseTX_FD uint16 = 16 + LLDPMAUType100BaseFX_HD uint16 = 17 + LLDPMAUType100BaseFX_FD uint16 = 18 + LLDPMAUType100BaseT2_HD uint16 = 19 + LLDPMAUType100BaseT2_FD uint16 = 20 + LLDPMAUType1000BaseX_HD uint16 = 21 + LLDPMAUType1000BaseX_FD uint16 = 22 + LLDPMAUType1000BaseLX_HD uint16 = 23 + LLDPMAUType1000BaseLX_FD uint16 = 24 + LLDPMAUType1000BaseSX_HD uint16 = 25 + LLDPMAUType1000BaseSX_FD uint16 = 26 + LLDPMAUType1000BaseCX_HD uint16 = 27 + LLDPMAUType1000BaseCX_FD uint16 = 28 + LLDPMAUType1000BaseT_HD uint16 = 29 + LLDPMAUType1000BaseT_FD uint16 = 30 + LLDPMAUType10GBaseX uint16 = 31 + LLDPMAUType10GBaseLX4 uint16 = 32 + LLDPMAUType10GBaseR uint16 = 33 + LLDPMAUType10GBaseER uint16 = 34 + LLDPMAUType10GBaseLR uint16 = 35 + LLDPMAUType10GBaseSR uint16 = 36 + LLDPMAUType10GBaseW uint16 = 37 + LLDPMAUType10GBaseEW uint16 = 38 + LLDPMAUType10GBaseLW uint16 = 39 + LLDPMAUType10GBaseSW uint16 = 40 + LLDPMAUType10GBaseCX4 uint16 = 41 + LLDPMAUType2BaseTL uint16 = 42 + LLDPMAUType10PASS_TS uint16 = 43 + LLDPMAUType100BaseBX10D uint16 = 44 + LLDPMAUType100BaseBX10U uint16 = 45 + LLDPMAUType100BaseLX10 uint16 = 46 + LLDPMAUType1000BaseBX10D uint16 = 47 + LLDPMAUType1000BaseBX10U uint16 = 48 + LLDPMAUType1000BaseLX10 uint16 = 49 + LLDPMAUType1000BasePX10D uint16 = 50 + LLDPMAUType1000BasePX10U uint16 = 51 + LLDPMAUType1000BasePX20D uint16 = 52 + LLDPMAUType1000BasePX20U uint16 = 53 + LLDPMAUType10GBaseT uint16 = 54 + LLDPMAUType10GBaseLRM uint16 = 55 + LLDPMAUType1000BaseKX uint16 = 56 + LLDPMAUType10GBaseKX4 uint16 = 57 + LLDPMAUType10GBaseKR uint16 = 58 + LLDPMAUType10_1GBasePRX_D1 uint16 = 59 + LLDPMAUType10_1GBasePRX_D2 uint16 = 60 + LLDPMAUType10_1GBasePRX_D3 uint16 = 61 + LLDPMAUType10_1GBasePRX_U1 uint16 = 62 + LLDPMAUType10_1GBasePRX_U2 uint16 = 63 + LLDPMAUType10_1GBasePRX_U3 uint16 = 64 + LLDPMAUType10GBasePR_D1 uint16 = 65 + LLDPMAUType10GBasePR_D2 uint16 = 66 + LLDPMAUType10GBasePR_D3 uint16 = 67 + LLDPMAUType10GBasePR_U1 uint16 = 68 + LLDPMAUType10GBasePR_U3 uint16 = 69 +) + +// From RFC 3636 - ifMauAutoNegCapAdvertisedBits +const ( + LLDPMAUPMDOther uint16 = 1 << 15 + LLDPMAUPMD10BaseT uint16 = 1 << 14 + LLDPMAUPMD10BaseT_FD uint16 = 1 << 13 + LLDPMAUPMD100BaseT4 uint16 = 1 << 12 + LLDPMAUPMD100BaseTX uint16 = 1 << 11 + LLDPMAUPMD100BaseTX_FD uint16 = 1 << 10 + LLDPMAUPMD100BaseT2 uint16 = 1 << 9 + LLDPMAUPMD100BaseT2_FD uint16 = 1 << 8 + LLDPMAUPMDFDXPAUSE uint16 = 1 << 7 + LLDPMAUPMDFDXAPAUSE uint16 = 1 << 6 + LLDPMAUPMDFDXSPAUSE uint16 = 1 << 5 + LLDPMAUPMDFDXBPAUSE uint16 = 1 << 4 + LLDPMAUPMD1000BaseX uint16 = 1 << 3 + LLDPMAUPMD1000BaseX_FD uint16 = 1 << 2 + LLDPMAUPMD1000BaseT uint16 = 1 << 1 + LLDPMAUPMD1000BaseT_FD uint16 = 1 << 0 +) + +// Inverted ifMauAutoNegCapAdvertisedBits if required +// (Some manufacturers misinterpreted the spec - +// see https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=1455) +const ( + LLDPMAUPMDOtherInv uint16 = 1 << 0 + LLDPMAUPMD10BaseTInv uint16 = 1 << 1 + LLDPMAUPMD10BaseT_FDInv uint16 = 1 << 2 + LLDPMAUPMD100BaseT4Inv uint16 = 1 << 3 + LLDPMAUPMD100BaseTXInv uint16 = 1 << 4 + LLDPMAUPMD100BaseTX_FDInv uint16 = 1 << 5 + LLDPMAUPMD100BaseT2Inv uint16 = 1 << 6 + LLDPMAUPMD100BaseT2_FDInv uint16 = 1 << 7 + LLDPMAUPMDFDXPAUSEInv uint16 = 1 << 8 + LLDPMAUPMDFDXAPAUSEInv uint16 = 1 << 9 + LLDPMAUPMDFDXSPAUSEInv uint16 = 1 << 10 + LLDPMAUPMDFDXBPAUSEInv uint16 = 1 << 11 + LLDPMAUPMD1000BaseXInv uint16 = 1 << 12 + LLDPMAUPMD1000BaseX_FDInv uint16 = 1 << 13 + LLDPMAUPMD1000BaseTInv uint16 = 1 << 14 + LLDPMAUPMD1000BaseT_FDInv uint16 = 1 << 15 +) + +type LLDPMACPHYConfigStatus struct { + AutoNegSupported bool + AutoNegEnabled bool + AutoNegCapability uint16 + MAUType uint16 +} + +// MDI Power options +const ( + LLDPMDIPowerPortClass byte = 1 << 0 + LLDPMDIPowerCapability byte = 1 << 1 + LLDPMDIPowerStatus byte = 1 << 2 + LLDPMDIPowerPairsAbility byte = 1 << 3 +) + +type LLDPPowerType byte + +type LLDPPowerSource byte + +type LLDPPowerPriority byte + +const ( + LLDPPowerPriorityUnknown LLDPPowerPriority = 0 + LLDPPowerPriorityMedium LLDPPowerPriority = 1 + LLDPPowerPriorityHigh LLDPPowerPriority = 2 + LLDPPowerPriorityLow LLDPPowerPriority = 3 +) + +type LLDPPowerViaMDI8023 struct { + PortClassPSE bool // false = PD + PSESupported bool + PSEEnabled bool + PSEPairsAbility bool + PSEPowerPair uint8 + PSEClass uint8 + Type LLDPPowerType + Source LLDPPowerSource + Priority LLDPPowerPriority + Requested uint16 // 1-510 Watts + Allocated uint16 // 1-510 Watts +} + +// LLDPInfo8023 represents the information carried in 802.3 Org-specific TLVs +type LLDPInfo8023 struct { + MACPHYConfigStatus LLDPMACPHYConfigStatus + PowerViaMDI LLDPPowerViaMDI8023 + LinkAggregation LLDPLinkAggregation + MTU uint16 +} + +// IEEE 802.1Qbg TLV Subtypes +const ( + LLDP8021QbgEVB uint8 = 0 + LLDP8021QbgCDCP uint8 = 1 + LLDP8021QbgVDP uint8 = 2 + LLDP8021QbgEVB22 uint8 = 13 +) + +// LLDPEVBCapabilities Types +const ( + LLDPEVBCapsSTD uint16 = 1 << 7 + LLDPEVBCapsRR uint16 = 1 << 6 + LLDPEVBCapsRTE uint16 = 1 << 2 + LLDPEVBCapsECP uint16 = 1 << 1 + LLDPEVBCapsVDP uint16 = 1 << 0 +) + +// LLDPEVBCapabilities represents the EVB capabilities of a device +type LLDPEVBCapabilities struct { + StandardBridging bool + ReflectiveRelay bool + RetransmissionTimerExponent bool + EdgeControlProtocol bool + VSIDiscoveryProtocol bool +} + +type LLDPEVBSettings struct { + Supported LLDPEVBCapabilities + Enabled LLDPEVBCapabilities + SupportedVSIs uint16 + ConfiguredVSIs uint16 + RTEExponent uint8 +} + +// LLDPInfo8021Qbg represents the information carried in 802.1Qbg Org-specific TLVs +type LLDPInfo8021Qbg struct { + EVBSettings LLDPEVBSettings +} + +type LLDPMediaSubtype uint8 + +// Media TLV Subtypes +const ( + LLDPMediaTypeCapabilities LLDPMediaSubtype = 1 + LLDPMediaTypeNetwork LLDPMediaSubtype = 2 + LLDPMediaTypeLocation LLDPMediaSubtype = 3 + LLDPMediaTypePower LLDPMediaSubtype = 4 + LLDPMediaTypeHardware LLDPMediaSubtype = 5 + LLDPMediaTypeFirmware LLDPMediaSubtype = 6 + LLDPMediaTypeSoftware LLDPMediaSubtype = 7 + LLDPMediaTypeSerial LLDPMediaSubtype = 8 + LLDPMediaTypeManufacturer LLDPMediaSubtype = 9 + LLDPMediaTypeModel LLDPMediaSubtype = 10 + LLDPMediaTypeAssetID LLDPMediaSubtype = 11 +) + +type LLDPMediaClass uint8 + +// Media Class Values +const ( + LLDPMediaClassUndefined LLDPMediaClass = 0 + LLDPMediaClassEndpointI LLDPMediaClass = 1 + LLDPMediaClassEndpointII LLDPMediaClass = 2 + LLDPMediaClassEndpointIII LLDPMediaClass = 3 + LLDPMediaClassNetwork LLDPMediaClass = 4 +) + +// LLDPMediaCapabilities Types +const ( + LLDPMediaCapsLLDP uint16 = 1 << 0 + LLDPMediaCapsNetwork uint16 = 1 << 1 + LLDPMediaCapsLocation uint16 = 1 << 2 + LLDPMediaCapsPowerPSE uint16 = 1 << 3 + LLDPMediaCapsPowerPD uint16 = 1 << 4 + LLDPMediaCapsInventory uint16 = 1 << 5 +) + +// LLDPMediaCapabilities represents the LLDP Media capabilities of a device +type LLDPMediaCapabilities struct { + Capabilities bool + NetworkPolicy bool + Location bool + PowerPSE bool + PowerPD bool + Inventory bool + Class LLDPMediaClass +} + +type LLDPApplicationType uint8 + +const ( + LLDPAppTypeReserved LLDPApplicationType = 0 + LLDPAppTypeVoice LLDPApplicationType = 1 + LLDPappTypeVoiceSignaling LLDPApplicationType = 2 + LLDPappTypeGuestVoice LLDPApplicationType = 3 + LLDPappTypeGuestVoiceSignaling LLDPApplicationType = 4 + LLDPappTypeSoftphoneVoice LLDPApplicationType = 5 + LLDPappTypeVideoConferencing LLDPApplicationType = 6 + LLDPappTypeStreamingVideo LLDPApplicationType = 7 + LLDPappTypeVideoSignaling LLDPApplicationType = 8 +) + +type LLDPNetworkPolicy struct { + ApplicationType LLDPApplicationType + Defined bool + Tagged bool + VLANId uint16 + L2Priority uint16 + DSCPValue uint8 +} + +type LLDPLocationFormat uint8 + +const ( + LLDPLocationFormatInvalid LLDPLocationFormat = 0 + LLDPLocationFormatCoordinate LLDPLocationFormat = 1 + LLDPLocationFormatAddress LLDPLocationFormat = 2 + LLDPLocationFormatECS LLDPLocationFormat = 3 +) + +type LLDPLocationAddressWhat uint8 + +const ( + LLDPLocationAddressWhatDHCP LLDPLocationAddressWhat = 0 + LLDPLocationAddressWhatNetwork LLDPLocationAddressWhat = 1 + LLDPLocationAddressWhatClient LLDPLocationAddressWhat = 2 +) + +type LLDPLocationAddressType uint8 + +const ( + LLDPLocationAddressTypeLanguage LLDPLocationAddressType = 0 + LLDPLocationAddressTypeNational LLDPLocationAddressType = 1 + LLDPLocationAddressTypeCounty LLDPLocationAddressType = 2 + LLDPLocationAddressTypeCity LLDPLocationAddressType = 3 + LLDPLocationAddressTypeCityDivision LLDPLocationAddressType = 4 + LLDPLocationAddressTypeNeighborhood LLDPLocationAddressType = 5 + LLDPLocationAddressTypeStreet LLDPLocationAddressType = 6 + LLDPLocationAddressTypeLeadingStreet LLDPLocationAddressType = 16 + LLDPLocationAddressTypeTrailingStreet LLDPLocationAddressType = 17 + LLDPLocationAddressTypeStreetSuffix LLDPLocationAddressType = 18 + LLDPLocationAddressTypeHouseNum LLDPLocationAddressType = 19 + LLDPLocationAddressTypeHouseSuffix LLDPLocationAddressType = 20 + LLDPLocationAddressTypeLandmark LLDPLocationAddressType = 21 + LLDPLocationAddressTypeAdditional LLDPLocationAddressType = 22 + LLDPLocationAddressTypeName LLDPLocationAddressType = 23 + LLDPLocationAddressTypePostal LLDPLocationAddressType = 24 + LLDPLocationAddressTypeBuilding LLDPLocationAddressType = 25 + LLDPLocationAddressTypeUnit LLDPLocationAddressType = 26 + LLDPLocationAddressTypeFloor LLDPLocationAddressType = 27 + LLDPLocationAddressTypeRoom LLDPLocationAddressType = 28 + LLDPLocationAddressTypePlace LLDPLocationAddressType = 29 + LLDPLocationAddressTypeScript LLDPLocationAddressType = 128 +) + +type LLDPLocationCoordinate struct { + LatitudeResolution uint8 + Latitude uint64 + LongitudeResolution uint8 + Longitude uint64 + AltitudeType uint8 + AltitudeResolution uint16 + Altitude uint32 + Datum uint8 +} + +type LLDPLocationAddressLine struct { + Type LLDPLocationAddressType + Value string +} + +type LLDPLocationAddress struct { + What LLDPLocationAddressWhat + CountryCode string + AddressLines []LLDPLocationAddressLine +} + +type LLDPLocationECS struct { + ELIN string +} + +// LLDP represents a physical location. +// Only one of the embedded types will contain values, depending on Format. +type LLDPLocation struct { + Format LLDPLocationFormat + Coordinate LLDPLocationCoordinate + Address LLDPLocationAddress + ECS LLDPLocationECS +} + +type LLDPPowerViaMDI struct { + Type LLDPPowerType + Source LLDPPowerSource + Priority LLDPPowerPriority + Value uint16 +} + +// LLDPInfoMedia represents the information carried in TR-41 Org-specific TLVs +type LLDPInfoMedia struct { + MediaCapabilities LLDPMediaCapabilities + NetworkPolicy LLDPNetworkPolicy + Location LLDPLocation + PowerViaMDI LLDPPowerViaMDI + HardwareRevision string + FirmwareRevision string + SoftwareRevision string + SerialNumber string + Manufacturer string + Model string + AssetID string +} + +type LLDPCisco2Subtype uint8 + +// Cisco2 TLV Subtypes +const ( + LLDPCisco2PowerViaMDI LLDPCisco2Subtype = 1 +) + +const ( + LLDPCiscoPSESupport uint8 = 1 << 0 + LLDPCiscoArchShared uint8 = 1 << 1 + LLDPCiscoPDSparePair uint8 = 1 << 2 + LLDPCiscoPSESparePair uint8 = 1 << 3 +) + +// LLDPInfoCisco2 represents the information carried in Cisco Org-specific TLVs +type LLDPInfoCisco2 struct { + PSEFourWirePoESupported bool + PDSparePairArchitectureShared bool + PDRequestSparePairPoEOn bool + PSESparePairPoEOn bool +} + +// Profinet Subtypes +type LLDPProfinetSubtype uint8 + +const ( + LLDPProfinetPNIODelay LLDPProfinetSubtype = 1 + LLDPProfinetPNIOPortStatus LLDPProfinetSubtype = 2 + LLDPProfinetPNIOMRPPortStatus LLDPProfinetSubtype = 4 + LLDPProfinetPNIOChassisMAC LLDPProfinetSubtype = 5 + LLDPProfinetPNIOPTCPStatus LLDPProfinetSubtype = 6 +) + +type LLDPPNIODelay struct { + RXLocal uint32 + RXRemote uint32 + TXLocal uint32 + TXRemote uint32 + CableLocal uint32 +} + +type LLDPPNIOPortStatus struct { + Class2 uint16 + Class3 uint16 +} + +type LLDPPNIOMRPPortStatus struct { + UUID []byte + Status uint16 +} + +type LLDPPNIOPTCPStatus struct { + MasterAddress []byte + SubdomainUUID []byte + IRDataUUID []byte + PeriodValid bool + PeriodLength uint32 + RedPeriodValid bool + RedPeriodBegin uint32 + OrangePeriodValid bool + OrangePeriodBegin uint32 + GreenPeriodValid bool + GreenPeriodBegin uint32 +} + +// LLDPInfoProfinet represents the information carried in Profinet Org-specific TLVs +type LLDPInfoProfinet struct { + PNIODelay LLDPPNIODelay + PNIOPortStatus LLDPPNIOPortStatus + PNIOMRPPortStatus LLDPPNIOMRPPortStatus + ChassisMAC []byte + PNIOPTCPStatus LLDPPNIOPTCPStatus +} + +// LayerType returns gopacket.LayerTypeLinkLayerDiscovery. +func (c *LinkLayerDiscovery) LayerType() gopacket.LayerType { + return LayerTypeLinkLayerDiscovery +} + +func decodeLinkLayerDiscovery(data []byte, p gopacket.PacketBuilder) error { + var vals []LinkLayerDiscoveryValue + vData := data[0:] + for len(vData) > 0 { + nbit := vData[0] & 0x01 + t := LLDPTLVType(vData[0] >> 1) + val := LinkLayerDiscoveryValue{Type: t, Length: uint16(nbit)<<8 + uint16(vData[1])} + if val.Length > 0 { + val.Value = vData[2 : val.Length+2] + } + vals = append(vals, val) + if t == LLDPTLVEnd { + break + } + if len(vData) < int(2+val.Length) { + return errors.New("Malformed LinkLayerDiscovery Header") + } + vData = vData[2+val.Length:] + } + if len(vals) < 4 { + return errors.New("Missing mandatory LinkLayerDiscovery TLV") + } + c := &LinkLayerDiscovery{} + gotEnd := false + for _, v := range vals { + switch v.Type { + case LLDPTLVEnd: + gotEnd = true + case LLDPTLVChassisID: + if len(v.Value) < 2 { + return errors.New("Malformed LinkLayerDiscovery ChassisID TLV") + } + c.ChassisID.Subtype = LLDPChassisIDSubType(v.Value[0]) + c.ChassisID.ID = v.Value[1:] + case LLDPTLVPortID: + if len(v.Value) < 2 { + return errors.New("Malformed LinkLayerDiscovery PortID TLV") + } + c.PortID.Subtype = LLDPPortIDSubType(v.Value[0]) + c.PortID.ID = v.Value[1:] + case LLDPTLVTTL: + if len(v.Value) < 2 { + return errors.New("Malformed LinkLayerDiscovery TTL TLV") + } + c.TTL = binary.BigEndian.Uint16(v.Value[0:2]) + default: + c.Values = append(c.Values, v) + } + } + if c.ChassisID.Subtype == 0 || c.PortID.Subtype == 0 || !gotEnd { + return errors.New("Missing mandatory LinkLayerDiscovery TLV") + } + c.Contents = data + p.AddLayer(c) + + info := &LinkLayerDiscoveryInfo{} + p.AddLayer(info) + for _, v := range c.Values { + switch v.Type { + case LLDPTLVPortDescription: + info.PortDescription = string(v.Value) + case LLDPTLVSysName: + info.SysName = string(v.Value) + case LLDPTLVSysDescription: + info.SysDescription = string(v.Value) + case LLDPTLVSysCapabilities: + if err := checkLLDPTLVLen(v, 4); err != nil { + return err + } + info.SysCapabilities.SystemCap = getCapabilities(binary.BigEndian.Uint16(v.Value[0:2])) + info.SysCapabilities.EnabledCap = getCapabilities(binary.BigEndian.Uint16(v.Value[2:4])) + case LLDPTLVMgmtAddress: + if err := checkLLDPTLVLen(v, 9); err != nil { + return err + } + mlen := v.Value[0] + if err := checkLLDPTLVLen(v, int(mlen+7)); err != nil { + return err + } + info.MgmtAddress.Subtype = IANAAddressFamily(v.Value[1]) + info.MgmtAddress.Address = v.Value[2 : mlen+1] + info.MgmtAddress.InterfaceSubtype = LLDPInterfaceSubtype(v.Value[mlen+1]) + info.MgmtAddress.InterfaceNumber = binary.BigEndian.Uint32(v.Value[mlen+2 : mlen+6]) + olen := v.Value[mlen+6] + if err := checkLLDPTLVLen(v, int(mlen+6+olen)); err != nil { + return err + } + info.MgmtAddress.OID = string(v.Value[mlen+9 : mlen+9+olen]) + case LLDPTLVOrgSpecific: + if err := checkLLDPTLVLen(v, 4); err != nil { + return err + } + info.OrgTLVs = append(info.OrgTLVs, LLDPOrgSpecificTLV{IEEEOUI(binary.BigEndian.Uint32(append([]byte{byte(0)}, v.Value[0:3]...))), uint8(v.Value[3]), v.Value[4:]}) + } + } + return nil +} + +func (l *LinkLayerDiscoveryInfo) Decode8021() (info LLDPInfo8021, err error) { + for _, o := range l.OrgTLVs { + if o.OUI != IEEEOUI8021 { + continue + } + switch o.SubType { + case LLDP8021SubtypePortVLANID: + if err = checkLLDPOrgSpecificLen(o, 2); err != nil { + return + } + info.PVID = binary.BigEndian.Uint16(o.Info[0:2]) + case LLDP8021SubtypeProtocolVLANID: + if err = checkLLDPOrgSpecificLen(o, 3); err != nil { + return + } + sup := (o.Info[0]&LLDPProtocolVLANIDCapability > 0) + en := (o.Info[0]&LLDPProtocolVLANIDStatus > 0) + id := binary.BigEndian.Uint16(o.Info[1:3]) + info.PPVIDs = append(info.PPVIDs, PortProtocolVLANID{sup, en, id}) + case LLDP8021SubtypeVLANName: + if err = checkLLDPOrgSpecificLen(o, 2); err != nil { + return + } + id := binary.BigEndian.Uint16(o.Info[0:2]) + info.VLANNames = append(info.VLANNames, VLANName{id, string(o.Info[3:])}) + case LLDP8021SubtypeProtocolIdentity: + if err = checkLLDPOrgSpecificLen(o, 1); err != nil { + return + } + l := int(o.Info[0]) + if l > 0 { + info.ProtocolIdentities = append(info.ProtocolIdentities, o.Info[1:1+l]) + } + case LLDP8021SubtypeVDIUsageDigest: + if err = checkLLDPOrgSpecificLen(o, 4); err != nil { + return + } + info.VIDUsageDigest = binary.BigEndian.Uint32(o.Info[0:4]) + case LLDP8021SubtypeManagementVID: + if err = checkLLDPOrgSpecificLen(o, 2); err != nil { + return + } + info.ManagementVID = binary.BigEndian.Uint16(o.Info[0:2]) + case LLDP8021SubtypeLinkAggregation: + if err = checkLLDPOrgSpecificLen(o, 5); err != nil { + return + } + sup := (o.Info[0]&LLDPAggregationCapability > 0) + en := (o.Info[0]&LLDPAggregationStatus > 0) + info.LinkAggregation = LLDPLinkAggregation{sup, en, binary.BigEndian.Uint32(o.Info[1:5])} + } + } + return +} + +func (l *LinkLayerDiscoveryInfo) Decode8023() (info LLDPInfo8023, err error) { + for _, o := range l.OrgTLVs { + if o.OUI != IEEEOUI8023 { + continue + } + switch o.SubType { + case LLDP8023SubtypeMACPHY: + if err = checkLLDPOrgSpecificLen(o, 5); err != nil { + return + } + sup := (o.Info[0]&LLDPMACPHYCapability > 0) + en := (o.Info[0]&LLDPMACPHYStatus > 0) + ca := binary.BigEndian.Uint16(o.Info[1:3]) + mau := binary.BigEndian.Uint16(o.Info[3:5]) + info.MACPHYConfigStatus = LLDPMACPHYConfigStatus{sup, en, ca, mau} + case LLDP8023SubtypeMDIPower: + if err = checkLLDPOrgSpecificLen(o, 3); err != nil { + return + } + info.PowerViaMDI.PortClassPSE = (o.Info[0]&LLDPMDIPowerPortClass > 0) + info.PowerViaMDI.PSESupported = (o.Info[0]&LLDPMDIPowerCapability > 0) + info.PowerViaMDI.PSEEnabled = (o.Info[0]&LLDPMDIPowerStatus > 0) + info.PowerViaMDI.PSEPairsAbility = (o.Info[0]&LLDPMDIPowerPairsAbility > 0) + info.PowerViaMDI.PSEPowerPair = uint8(o.Info[1]) + info.PowerViaMDI.PSEClass = uint8(o.Info[2]) + if len(o.Info) >= 7 { + info.PowerViaMDI.Type = LLDPPowerType((o.Info[3] & 0xc0) >> 6) + info.PowerViaMDI.Source = LLDPPowerSource((o.Info[3] & 0x30) >> 4) + if info.PowerViaMDI.Type == 1 || info.PowerViaMDI.Type == 3 { + info.PowerViaMDI.Source += 128 // For Stringify purposes + } + info.PowerViaMDI.Priority = LLDPPowerPriority(o.Info[3] & 0x0f) + info.PowerViaMDI.Requested = binary.BigEndian.Uint16(o.Info[4:6]) + info.PowerViaMDI.Allocated = binary.BigEndian.Uint16(o.Info[6:8]) + } + case LLDP8023SubtypeLinkAggregation: + if err = checkLLDPOrgSpecificLen(o, 5); err != nil { + return + } + sup := (o.Info[0]&LLDPAggregationCapability > 0) + en := (o.Info[0]&LLDPAggregationStatus > 0) + info.LinkAggregation = LLDPLinkAggregation{sup, en, binary.BigEndian.Uint32(o.Info[1:5])} + case LLDP8023SubtypeMTU: + if err = checkLLDPOrgSpecificLen(o, 2); err != nil { + return + } + info.MTU = binary.BigEndian.Uint16(o.Info[0:2]) + } + } + return +} + +func (l *LinkLayerDiscoveryInfo) Decode8021Qbg() (info LLDPInfo8021Qbg, err error) { + for _, o := range l.OrgTLVs { + if o.OUI != IEEEOUI8021Qbg { + continue + } + switch o.SubType { + case LLDP8021QbgEVB: + if err = checkLLDPOrgSpecificLen(o, 9); err != nil { + return + } + info.EVBSettings.Supported = getEVBCapabilities(binary.BigEndian.Uint16(o.Info[0:2])) + info.EVBSettings.Enabled = getEVBCapabilities(binary.BigEndian.Uint16(o.Info[2:4])) + info.EVBSettings.SupportedVSIs = binary.BigEndian.Uint16(o.Info[4:6]) + info.EVBSettings.ConfiguredVSIs = binary.BigEndian.Uint16(o.Info[6:8]) + info.EVBSettings.RTEExponent = uint8(o.Info[8]) + } + } + return +} + +func (l *LinkLayerDiscoveryInfo) DecodeMedia() (info LLDPInfoMedia, err error) { + for _, o := range l.OrgTLVs { + if o.OUI != IEEEOUIMedia { + continue + } + switch LLDPMediaSubtype(o.SubType) { + case LLDPMediaTypeCapabilities: + if err = checkLLDPOrgSpecificLen(o, 3); err != nil { + return + } + b := binary.BigEndian.Uint16(o.Info[0:2]) + info.MediaCapabilities.Capabilities = (b & LLDPMediaCapsLLDP) > 0 + info.MediaCapabilities.NetworkPolicy = (b & LLDPMediaCapsNetwork) > 0 + info.MediaCapabilities.Location = (b & LLDPMediaCapsLocation) > 0 + info.MediaCapabilities.PowerPSE = (b & LLDPMediaCapsPowerPSE) > 0 + info.MediaCapabilities.PowerPD = (b & LLDPMediaCapsPowerPD) > 0 + info.MediaCapabilities.Inventory = (b & LLDPMediaCapsInventory) > 0 + info.MediaCapabilities.Class = LLDPMediaClass(o.Info[2]) + case LLDPMediaTypeNetwork: + if err = checkLLDPOrgSpecificLen(o, 4); err != nil { + return + } + info.NetworkPolicy.ApplicationType = LLDPApplicationType(o.Info[0]) + b := binary.BigEndian.Uint16(o.Info[1:3]) + info.NetworkPolicy.Defined = (b & 0x8000) == 0 + info.NetworkPolicy.Tagged = (b & 0x4000) > 0 + info.NetworkPolicy.VLANId = (b & 0x1ffe) >> 1 + b = binary.BigEndian.Uint16(o.Info[2:4]) + info.NetworkPolicy.L2Priority = (b & 0x01c0) >> 6 + info.NetworkPolicy.DSCPValue = uint8(o.Info[3] & 0x3f) + case LLDPMediaTypeLocation: + if err = checkLLDPOrgSpecificLen(o, 1); err != nil { + return + } + info.Location.Format = LLDPLocationFormat(o.Info[0]) + o.Info = o.Info[1:] + switch info.Location.Format { + case LLDPLocationFormatCoordinate: + if err = checkLLDPOrgSpecificLen(o, 16); err != nil { + return + } + info.Location.Coordinate.LatitudeResolution = uint8(o.Info[0]&0xfc) >> 2 + b := binary.BigEndian.Uint64(o.Info[0:8]) + info.Location.Coordinate.Latitude = (b & 0x03ffffffff000000) >> 24 + info.Location.Coordinate.LongitudeResolution = uint8(o.Info[5]&0xfc) >> 2 + b = binary.BigEndian.Uint64(o.Info[5:13]) + info.Location.Coordinate.Longitude = (b & 0x03ffffffff000000) >> 24 + info.Location.Coordinate.AltitudeType = uint8((o.Info[10] & 0x30) >> 4) + b1 := binary.BigEndian.Uint16(o.Info[10:12]) + info.Location.Coordinate.AltitudeResolution = (b1 & 0xfc0) >> 6 + b2 := binary.BigEndian.Uint32(o.Info[11:15]) + info.Location.Coordinate.Altitude = b2 & 0x3fffffff + info.Location.Coordinate.Datum = uint8(o.Info[15]) + case LLDPLocationFormatAddress: + if err = checkLLDPOrgSpecificLen(o, 3); err != nil { + return + } + //ll := uint8(o.Info[0]) + info.Location.Address.What = LLDPLocationAddressWhat(o.Info[1]) + info.Location.Address.CountryCode = string(o.Info[2:4]) + data := o.Info[4:] + for len(data) > 1 { + aType := LLDPLocationAddressType(data[0]) + aLen := int(data[1]) + if len(data) >= aLen+2 { + info.Location.Address.AddressLines = append(info.Location.Address.AddressLines, LLDPLocationAddressLine{aType, string(data[2 : aLen+2])}) + data = data[aLen+2:] + } else { + break + } + } + case LLDPLocationFormatECS: + info.Location.ECS.ELIN = string(o.Info) + } + case LLDPMediaTypePower: + if err = checkLLDPOrgSpecificLen(o, 3); err != nil { + return + } + info.PowerViaMDI.Type = LLDPPowerType((o.Info[0] & 0xc0) >> 6) + info.PowerViaMDI.Source = LLDPPowerSource((o.Info[0] & 0x30) >> 4) + if info.PowerViaMDI.Type == 1 || info.PowerViaMDI.Type == 3 { + info.PowerViaMDI.Source += 128 // For Stringify purposes + } + info.PowerViaMDI.Priority = LLDPPowerPriority(o.Info[0] & 0x0f) + info.PowerViaMDI.Value = binary.BigEndian.Uint16(o.Info[1:3]) * 100 // 0 to 102.3 w, 0.1W increments + case LLDPMediaTypeHardware: + info.HardwareRevision = string(o.Info) + case LLDPMediaTypeFirmware: + info.FirmwareRevision = string(o.Info) + case LLDPMediaTypeSoftware: + info.SoftwareRevision = string(o.Info) + case LLDPMediaTypeSerial: + info.SerialNumber = string(o.Info) + case LLDPMediaTypeManufacturer: + info.Manufacturer = string(o.Info) + case LLDPMediaTypeModel: + info.Model = string(o.Info) + case LLDPMediaTypeAssetID: + info.AssetID = string(o.Info) + } + } + return +} + +func (l *LinkLayerDiscoveryInfo) DecodeCisco2() (info LLDPInfoCisco2, err error) { + for _, o := range l.OrgTLVs { + if o.OUI != IEEEOUICisco2 { + continue + } + switch LLDPCisco2Subtype(o.SubType) { + case LLDPCisco2PowerViaMDI: + if err = checkLLDPOrgSpecificLen(o, 1); err != nil { + return + } + info.PSEFourWirePoESupported = (o.Info[0] & LLDPCiscoPSESupport) > 0 + info.PDSparePairArchitectureShared = (o.Info[0] & LLDPCiscoArchShared) > 0 + info.PDRequestSparePairPoEOn = (o.Info[0] & LLDPCiscoPDSparePair) > 0 + info.PSESparePairPoEOn = (o.Info[0] & LLDPCiscoPSESparePair) > 0 + } + } + return +} + +func (l *LinkLayerDiscoveryInfo) DecodeProfinet() (info LLDPInfoProfinet, err error) { + for _, o := range l.OrgTLVs { + if o.OUI != IEEEOUIProfinet { + continue + } + switch LLDPProfinetSubtype(o.SubType) { + case LLDPProfinetPNIODelay: + if err = checkLLDPOrgSpecificLen(o, 20); err != nil { + return + } + info.PNIODelay.RXLocal = binary.BigEndian.Uint32(o.Info[0:4]) + info.PNIODelay.RXRemote = binary.BigEndian.Uint32(o.Info[4:8]) + info.PNIODelay.TXLocal = binary.BigEndian.Uint32(o.Info[8:12]) + info.PNIODelay.TXRemote = binary.BigEndian.Uint32(o.Info[12:16]) + info.PNIODelay.CableLocal = binary.BigEndian.Uint32(o.Info[16:20]) + case LLDPProfinetPNIOPortStatus: + if err = checkLLDPOrgSpecificLen(o, 4); err != nil { + return + } + info.PNIOPortStatus.Class2 = binary.BigEndian.Uint16(o.Info[0:2]) + info.PNIOPortStatus.Class3 = binary.BigEndian.Uint16(o.Info[2:4]) + case LLDPProfinetPNIOMRPPortStatus: + if err = checkLLDPOrgSpecificLen(o, 18); err != nil { + return + } + info.PNIOMRPPortStatus.UUID = o.Info[0:16] + info.PNIOMRPPortStatus.Status = binary.BigEndian.Uint16(o.Info[16:18]) + case LLDPProfinetPNIOChassisMAC: + if err = checkLLDPOrgSpecificLen(o, 6); err != nil { + return + } + info.ChassisMAC = o.Info[0:6] + case LLDPProfinetPNIOPTCPStatus: + if err = checkLLDPOrgSpecificLen(o, 54); err != nil { + return + } + info.PNIOPTCPStatus.MasterAddress = o.Info[0:6] + info.PNIOPTCPStatus.SubdomainUUID = o.Info[6:22] + info.PNIOPTCPStatus.IRDataUUID = o.Info[22:38] + b := binary.BigEndian.Uint32(o.Info[38:42]) + info.PNIOPTCPStatus.PeriodValid = (b & 0x80000000) > 0 + info.PNIOPTCPStatus.PeriodLength = b & 0x7fffffff + b = binary.BigEndian.Uint32(o.Info[42:46]) + info.PNIOPTCPStatus.RedPeriodValid = (b & 0x80000000) > 0 + info.PNIOPTCPStatus.RedPeriodBegin = b & 0x7fffffff + b = binary.BigEndian.Uint32(o.Info[46:50]) + info.PNIOPTCPStatus.OrangePeriodValid = (b & 0x80000000) > 0 + info.PNIOPTCPStatus.OrangePeriodBegin = b & 0x7fffffff + b = binary.BigEndian.Uint32(o.Info[50:54]) + info.PNIOPTCPStatus.GreenPeriodValid = (b & 0x80000000) > 0 + info.PNIOPTCPStatus.GreenPeriodBegin = b & 0x7fffffff + } + } + return +} + +// LayerType returns gopacket.LayerTypeLinkLayerDiscoveryInfo. +func (c *LinkLayerDiscoveryInfo) LayerType() gopacket.LayerType { + return LayerTypeLinkLayerDiscoveryInfo +} + +func getCapabilities(v uint16) (c LLDPCapabilities) { + c.Other = (v&LLDPCapsOther > 0) + c.Repeater = (v&LLDPCapsRepeater > 0) + c.Bridge = (v&LLDPCapsBridge > 0) + c.WLANAP = (v&LLDPCapsWLANAP > 0) + c.Router = (v&LLDPCapsRouter > 0) + c.Phone = (v&LLDPCapsPhone > 0) + c.DocSis = (v&LLDPCapsDocSis > 0) + c.StationOnly = (v&LLDPCapsStationOnly > 0) + c.CVLAN = (v&LLDPCapsCVLAN > 0) + c.SVLAN = (v&LLDPCapsSVLAN > 0) + c.TMPR = (v&LLDPCapsTmpr > 0) + return +} + +func getEVBCapabilities(v uint16) (c LLDPEVBCapabilities) { + c.StandardBridging = (v & LLDPEVBCapsSTD) > 0 + c.StandardBridging = (v & LLDPEVBCapsSTD) > 0 + c.ReflectiveRelay = (v & LLDPEVBCapsRR) > 0 + c.RetransmissionTimerExponent = (v & LLDPEVBCapsRTE) > 0 + c.EdgeControlProtocol = (v & LLDPEVBCapsECP) > 0 + c.VSIDiscoveryProtocol = (v & LLDPEVBCapsVDP) > 0 + return +} + +func (t LLDPTLVType) String() (s string) { + switch t { + case LLDPTLVEnd: + s = "TLV End" + case LLDPTLVChassisID: + s = "Chassis ID" + case LLDPTLVPortID: + s = "Port ID" + case LLDPTLVTTL: + s = "TTL" + case LLDPTLVPortDescription: + s = "Port Description" + case LLDPTLVSysName: + s = "System Name" + case LLDPTLVSysDescription: + s = "System Description" + case LLDPTLVSysCapabilities: + s = "System Capabilities" + case LLDPTLVMgmtAddress: + s = "Management Address" + case LLDPTLVOrgSpecific: + s = "Organisation Specific" + default: + s = "Unknown" + } + return +} + +func (t LLDPChassisIDSubType) String() (s string) { + switch t { + case LLDPChassisIDSubTypeReserved: + s = "Reserved" + case LLDPChassisIDSubTypeChassisComp: + s = "Chassis Component" + case LLDPChassisIDSubtypeIfaceAlias: + s = "Interface Alias" + case LLDPChassisIDSubTypePortComp: + s = "Port Component" + case LLDPChassisIDSubTypeMACAddr: + s = "MAC Address" + case LLDPChassisIDSubTypeNetworkAddr: + s = "Network Address" + case LLDPChassisIDSubtypeIfaceName: + s = "Interface Name" + case LLDPChassisIDSubTypeLocal: + s = "Local" + default: + s = "Unknown" + } + return +} + +func (t LLDPPortIDSubType) String() (s string) { + switch t { + case LLDPPortIDSubtypeReserved: + s = "Reserved" + case LLDPPortIDSubtypeIfaceAlias: + s = "Interface Alias" + case LLDPPortIDSubtypePortComp: + s = "Port Component" + case LLDPPortIDSubtypeMACAddr: + s = "MAC Address" + case LLDPPortIDSubtypeNetworkAddr: + s = "Network Address" + case LLDPPortIDSubtypeIfaceName: + s = "Interface Name" + case LLDPPortIDSubtypeAgentCircuitID: + s = "Agent Circuit ID" + case LLDPPortIDSubtypeLocal: + s = "Local" + default: + s = "Unknown" + } + return +} + +func (t IANAAddressFamily) String() (s string) { + switch t { + case IANAAddressFamilyReserved: + s = "Reserved" + case IANAAddressFamilyIPV4: + s = "IPv4" + case IANAAddressFamilyIPV6: + s = "IPv6" + case IANAAddressFamilyNSAP: + s = "NSAP" + case IANAAddressFamilyHDLC: + s = "HDLC" + case IANAAddressFamilyBBN1822: + s = "BBN 1822" + case IANAAddressFamily802: + s = "802 media plus Ethernet 'canonical format'" + case IANAAddressFamilyE163: + s = "E.163" + case IANAAddressFamilyE164: + s = "E.164 (SMDS, Frame Relay, ATM)" + case IANAAddressFamilyF69: + s = "F.69 (Telex)" + case IANAAddressFamilyX121: + s = "X.121, X.25, Frame Relay" + case IANAAddressFamilyIPX: + s = "IPX" + case IANAAddressFamilyAtalk: + s = "Appletalk" + case IANAAddressFamilyDecnet: + s = "Decnet IV" + case IANAAddressFamilyBanyan: + s = "Banyan Vines" + case IANAAddressFamilyE164NSAP: + s = "E.164 with NSAP format subaddress" + case IANAAddressFamilyDNS: + s = "DNS" + case IANAAddressFamilyDistname: + s = "Distinguished Name" + case IANAAddressFamilyASNumber: + s = "AS Number" + case IANAAddressFamilyXTPIPV4: + s = "XTP over IP version 4" + case IANAAddressFamilyXTPIPV6: + s = "XTP over IP version 6" + case IANAAddressFamilyXTP: + s = "XTP native mode XTP" + case IANAAddressFamilyFcWWPN: + s = "Fibre Channel World-Wide Port Name" + case IANAAddressFamilyFcWWNN: + s = "Fibre Channel World-Wide Node Name" + case IANAAddressFamilyGWID: + s = "GWID" + case IANAAddressFamilyL2VPN: + s = "AFI for Layer 2 VPN" + default: + s = "Unknown" + } + return +} + +func (t LLDPInterfaceSubtype) String() (s string) { + switch t { + case LLDPInterfaceSubtypeUnknown: + s = "Unknown" + case LLDPInterfaceSubtypeifIndex: + s = "IfIndex" + case LLDPInterfaceSubtypeSysPort: + s = "System Port Number" + default: + s = "Unknown" + } + return +} + +func (t LLDPPowerType) String() (s string) { + switch t { + case 0: + s = "Type 2 PSE Device" + case 1: + s = "Type 2 PD Device" + case 2: + s = "Type 1 PSE Device" + case 3: + s = "Type 1 PD Device" + default: + s = "Unknown" + } + return +} + +func (t LLDPPowerSource) String() (s string) { + switch t { + // PD Device + case 0: + s = "Unknown" + case 1: + s = "PSE" + case 2: + s = "Local" + case 3: + s = "PSE and Local" + // PSE Device (Actual value + 128) + case 128: + s = "Unknown" + case 129: + s = "Primary Power Source" + case 130: + s = "Backup Power Source" + default: + s = "Unknown" + } + return +} + +func (t LLDPPowerPriority) String() (s string) { + switch t { + case 0: + s = "Unknown" + case 1: + s = "Critical" + case 2: + s = "High" + case 3: + s = "Low" + default: + s = "Unknown" + } + return +} + +func (t LLDPMediaSubtype) String() (s string) { + switch t { + case LLDPMediaTypeCapabilities: + s = "Media Capabilities " + case LLDPMediaTypeNetwork: + s = "Network Policy" + case LLDPMediaTypeLocation: + s = "Location Identification" + case LLDPMediaTypePower: + s = "Extended Power-via-MDI" + case LLDPMediaTypeHardware: + s = "Hardware Revision" + case LLDPMediaTypeFirmware: + s = "Firmware Revision" + case LLDPMediaTypeSoftware: + s = "Software Revision" + case LLDPMediaTypeSerial: + s = "Serial Number" + case LLDPMediaTypeManufacturer: + s = "Manufacturer" + case LLDPMediaTypeModel: + s = "Model" + case LLDPMediaTypeAssetID: + s = "Asset ID" + default: + s = "Unknown" + } + return +} + +func (t LLDPMediaClass) String() (s string) { + switch t { + case LLDPMediaClassUndefined: + s = "Undefined" + case LLDPMediaClassEndpointI: + s = "Endpoint Class I" + case LLDPMediaClassEndpointII: + s = "Endpoint Class II" + case LLDPMediaClassEndpointIII: + s = "Endpoint Class III" + case LLDPMediaClassNetwork: + s = "Network connectivity " + default: + s = "Unknown" + } + return +} + +func (t LLDPApplicationType) String() (s string) { + switch t { + case LLDPAppTypeReserved: + s = "Reserved" + case LLDPAppTypeVoice: + s = "Voice" + case LLDPappTypeVoiceSignaling: + s = "Voice Signaling" + case LLDPappTypeGuestVoice: + s = "Guest Voice" + case LLDPappTypeGuestVoiceSignaling: + s = "Guest Voice Signaling" + case LLDPappTypeSoftphoneVoice: + s = "Softphone Voice" + case LLDPappTypeVideoConferencing: + s = "Video Conferencing" + case LLDPappTypeStreamingVideo: + s = "Streaming Video" + case LLDPappTypeVideoSignaling: + s = "Video Signaling" + default: + s = "Unknown" + } + return +} + +func (t LLDPLocationFormat) String() (s string) { + switch t { + case LLDPLocationFormatInvalid: + s = "Invalid" + case LLDPLocationFormatCoordinate: + s = "Coordinate-based LCI" + case LLDPLocationFormatAddress: + s = "Address-based LCO" + case LLDPLocationFormatECS: + s = "ECS ELIN" + default: + s = "Unknown" + } + return +} + +func (t LLDPLocationAddressType) String() (s string) { + switch t { + case LLDPLocationAddressTypeLanguage: + s = "Language" + case LLDPLocationAddressTypeNational: + s = "National subdivisions (province, state, etc)" + case LLDPLocationAddressTypeCounty: + s = "County, parish, district" + case LLDPLocationAddressTypeCity: + s = "City, township" + case LLDPLocationAddressTypeCityDivision: + s = "City division, borough, ward" + case LLDPLocationAddressTypeNeighborhood: + s = "Neighborhood, block" + case LLDPLocationAddressTypeStreet: + s = "Street" + case LLDPLocationAddressTypeLeadingStreet: + s = "Leading street direction" + case LLDPLocationAddressTypeTrailingStreet: + s = "Trailing street suffix" + case LLDPLocationAddressTypeStreetSuffix: + s = "Street suffix" + case LLDPLocationAddressTypeHouseNum: + s = "House number" + case LLDPLocationAddressTypeHouseSuffix: + s = "House number suffix" + case LLDPLocationAddressTypeLandmark: + s = "Landmark or vanity address" + case LLDPLocationAddressTypeAdditional: + s = "Additional location information" + case LLDPLocationAddressTypeName: + s = "Name" + case LLDPLocationAddressTypePostal: + s = "Postal/ZIP code" + case LLDPLocationAddressTypeBuilding: + s = "Building" + case LLDPLocationAddressTypeUnit: + s = "Unit" + case LLDPLocationAddressTypeFloor: + s = "Floor" + case LLDPLocationAddressTypeRoom: + s = "Room number" + case LLDPLocationAddressTypePlace: + s = "Place type" + case LLDPLocationAddressTypeScript: + s = "Script" + default: + s = "Unknown" + } + return +} + +func checkLLDPTLVLen(v LinkLayerDiscoveryValue, l int) (err error) { + if len(v.Value) < l { + err = fmt.Errorf("Invalid TLV %v length %d (wanted mimimum %v", v.Type, len(v.Value), l) + } + return +} + +func checkLLDPOrgSpecificLen(o LLDPOrgSpecificTLV, l int) (err error) { + if len(o.Info) < l { + err = fmt.Errorf("Invalid Org Specific TLV %v length %d (wanted minimum %v)", o.SubType, len(o.Info), l) + } + return +} diff --git a/vendor/github.com/google/gopacket/layers/loopback.go b/vendor/github.com/google/gopacket/layers/loopback.go new file mode 100644 index 0000000..839f760 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/loopback.go @@ -0,0 +1,80 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "errors" + "fmt" + + "github.com/google/gopacket" +) + +// Loopback contains the header for loopback encapsulation. This header is +// used by both BSD and OpenBSD style loopback decoding (pcap's DLT_NULL +// and DLT_LOOP, respectively). +type Loopback struct { + BaseLayer + Family ProtocolFamily +} + +// LayerType returns LayerTypeLoopback. +func (l *Loopback) LayerType() gopacket.LayerType { return LayerTypeLoopback } + +// DecodeFromBytes decodes the given bytes into this layer. +func (l *Loopback) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 4 { + return errors.New("Loopback packet too small") + } + + // 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.Family = ProtocolFamily(prot) + l.BaseLayer = BaseLayer{data[:4], data[4:]} + return nil +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (l *Loopback) CanDecode() gopacket.LayerClass { + return LayerTypeLoopback +} + +// NextLayerType returns the layer type contained by this DecodingLayer. +func (l *Loopback) NextLayerType() gopacket.LayerType { + return l.Family.LayerType() +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +func (l *Loopback) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + bytes, err := b.PrependBytes(4) + if err != nil { + return err + } + binary.LittleEndian.PutUint32(bytes, uint32(l.Family)) + return nil +} + +func decodeLoopback(data []byte, p gopacket.PacketBuilder) error { + l := Loopback{} + if err := l.DecodeFromBytes(data, gopacket.NilDecodeFeedback); err != nil { + return err + } + p.AddLayer(&l) + return p.NextDecoder(l.Family) +} diff --git a/vendor/github.com/google/gopacket/layers/mpls.go b/vendor/github.com/google/gopacket/layers/mpls.go new file mode 100644 index 0000000..83079a0 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/mpls.go @@ -0,0 +1,87 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "errors" + "github.com/google/gopacket" +) + +// MPLS is the MPLS packet header. +type MPLS struct { + BaseLayer + Label uint32 + TrafficClass uint8 + StackBottom bool + TTL uint8 +} + +// LayerType returns gopacket.LayerTypeMPLS. +func (m *MPLS) LayerType() gopacket.LayerType { return LayerTypeMPLS } + +// ProtocolGuessingDecoder attempts to guess the protocol of the bytes it's +// given, then decode the packet accordingly. Its algorithm for guessing is: +// If the packet starts with byte 0x45-0x4F: IPv4 +// If the packet starts with byte 0x60-0x6F: IPv6 +// Otherwise: Error +// See draft-hsmit-isis-aal5mux-00.txt for more detail on this approach. +type ProtocolGuessingDecoder struct{} + +func (ProtocolGuessingDecoder) Decode(data []byte, p gopacket.PacketBuilder) error { + switch data[0] { + // 0x40 | header_len, where header_len is at least 5. + case 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f: + return decodeIPv4(data, p) + // IPv6 can start with any byte whose first 4 bits are 0x6. + case 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f: + return decodeIPv6(data, p) + } + return errors.New("Unable to guess protocol of packet data") +} + +// MPLSPayloadDecoder is the decoder used to data encapsulated by each MPLS +// layer. MPLS contains no type information, so we have to explicitly decide +// which decoder to use. This is initially set to ProtocolGuessingDecoder, our +// simple attempt at guessing protocols based on the first few bytes of data +// available to us. However, if you know that in your environment MPLS always +// encapsulates a specific protocol, you may reset this. +var MPLSPayloadDecoder gopacket.Decoder = ProtocolGuessingDecoder{} + +func decodeMPLS(data []byte, p gopacket.PacketBuilder) error { + decoded := binary.BigEndian.Uint32(data[:4]) + mpls := &MPLS{ + Label: decoded >> 12, + TrafficClass: uint8(decoded>>9) & 0x7, + StackBottom: decoded&0x100 != 0, + TTL: uint8(decoded), + BaseLayer: BaseLayer{data[:4], data[4:]}, + } + p.AddLayer(mpls) + if mpls.StackBottom { + return p.NextDecoder(MPLSPayloadDecoder) + } + return p.NextDecoder(gopacket.DecodeFunc(decodeMPLS)) +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (m *MPLS) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + bytes, err := b.PrependBytes(4) + if err != nil { + return err + } + encoded := m.Label << 12 + encoded |= uint32(m.TrafficClass) << 9 + encoded |= uint32(m.TTL) + if m.StackBottom { + encoded |= 0x100 + } + binary.BigEndian.PutUint32(bytes, encoded) + return nil +} diff --git a/vendor/github.com/google/gopacket/layers/mpls_test.go b/vendor/github.com/google/gopacket/layers/mpls_test.go new file mode 100644 index 0000000..e0a2b95 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/mpls_test.go @@ -0,0 +1,96 @@ +// Copyright 2016 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "reflect" + "testing" + + "github.com/google/gopacket" +) + +// testPacketMPLS +// Ethernet II, Src: cc:15:14:64:00:00 (cc:15:14:64:00:00), Dst: cc:13:14:64:00:01 (cc:13:14:64:00:01) +// MultiProtocol Label Switching Header, Label: 17, Exp: 0, S: 0, TTL: 254 +// MultiProtocol Label Switching Header, Label: 19, Exp: 0, S: 1, TTL: 254 +// Internet Protocol Version 4, Src: 12.0.0.1, Dst: 2.2.2.2 +// Internet Control Message Protocol +// 0000 cc 13 14 64 00 01 cc 15 14 64 00 00 88 47 00 01 ...d.....d...G.. +// 0010 10 fe 00 01 31 fe 45 00 00 64 00 39 00 00 fe 01 ....1.E..d.9.... +// 0020 ac 5b 0c 00 00 01 02 02 02 02 08 00 3a 6b 00 0b .[..........:k.. +// 0030 00 02 00 00 00 00 00 3e 43 94 ab cd ab cd ab cd .......>C....... +// 0040 ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd ................ +// 0050 ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd ................ +// 0060 ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd ................ +// 0070 ab cd ab cd ab cd ab cd ab cd .......... + +var testPacketMPLS = []byte{ + 0xcc, 0x13, 0x14, 0x64, 0x00, 0x01, 0xcc, 0x15, 0x14, 0x64, 0x00, 0x00, 0x88, 0x47, 0x00, 0x01, + 0x10, 0xfe, 0x00, 0x01, 0x31, 0xfe, 0x45, 0x00, 0x00, 0x64, 0x00, 0x39, 0x00, 0x00, 0xfe, 0x01, + 0xac, 0x5b, 0x0c, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x08, 0x00, 0x3a, 0x6b, 0x00, 0x0b, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x43, 0x94, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, +} + +func TestPacketMPLS(t *testing.T) { + p := gopacket.NewPacket(testPacketMPLS, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeMPLS, LayerTypeMPLS, LayerTypeIPv4, LayerTypeICMPv4, gopacket.LayerTypePayload}, t) + if got, ok := p.Layers()[1].(*MPLS); ok { + want := &MPLS{ + BaseLayer: BaseLayer{ + Contents: []byte{0x00, 0x01, 0x10, 0xfe}, + Payload: []byte{0x00, 0x01, 0x31, 0xfe, 0x45, 0x00, 0x00, 0x64, 0x00, 0x39, 0x00, 0x00, 0xfe, 0x01, + 0xac, 0x5b, 0x0c, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x08, 0x00, 0x3a, 0x6b, 0x00, 0x0b, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x43, 0x94, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd}, + }, + Label: 17, + TrafficClass: 0, + StackBottom: false, + TTL: 254, + } + if !reflect.DeepEqual(want, got) { + t.Errorf("MPLS layer 1 mismatch, \nwant %#v\ngot %#v\n", want, got) + } + } + if got, ok := p.Layers()[2].(*MPLS); ok { + want := &MPLS{ + BaseLayer: BaseLayer{ + Contents: []byte{0x00, 0x01, 0x31, 0xfe}, + Payload: []byte{0x45, 0x00, 0x00, 0x64, 0x00, 0x39, 0x00, 0x00, 0xfe, 0x01, + 0xac, 0x5b, 0x0c, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x08, 0x00, 0x3a, 0x6b, 0x00, 0x0b, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x43, 0x94, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd}, + }, + Label: 19, + TrafficClass: 0, + StackBottom: true, + TTL: 254, + } + if !reflect.DeepEqual(want, got) { + t.Errorf("MPLS layer 2 mismatch, \nwant %#v\ngot %#v\n", want, got) + } + } +} + +func BenchmarkDecodePacketMPLS(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketMPLS, LinkTypeEthernet, gopacket.NoCopy) + } +} diff --git a/vendor/github.com/google/gopacket/layers/ndp.go b/vendor/github.com/google/gopacket/layers/ndp.go new file mode 100644 index 0000000..f7ca1b2 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/ndp.go @@ -0,0 +1,611 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +// Enum types courtesy of... +// http://anonsvn.wireshark.org/wireshark/trunk/epan/dissectors/packet-ndp.c + +package layers + +import ( + "fmt" + "github.com/google/gopacket" + "net" +) + +type NDPChassisType uint8 + +// Nortel Chassis Types +const ( + NDPChassisother NDPChassisType = 1 + NDPChassis3000 NDPChassisType = 2 + NDPChassis3030 NDPChassisType = 3 + NDPChassis2310 NDPChassisType = 4 + NDPChassis2810 NDPChassisType = 5 + NDPChassis2912 NDPChassisType = 6 + NDPChassis2914 NDPChassisType = 7 + NDPChassis271x NDPChassisType = 8 + NDPChassis2813 NDPChassisType = 9 + NDPChassis2814 NDPChassisType = 10 + NDPChassis2915 NDPChassisType = 11 + NDPChassis5000 NDPChassisType = 12 + NDPChassis2813SA NDPChassisType = 13 + NDPChassis2814SA NDPChassisType = 14 + NDPChassis810M NDPChassisType = 15 + NDPChassisEthercell NDPChassisType = 16 + NDPChassis5005 NDPChassisType = 17 + NDPChassisAlcatelEWC NDPChassisType = 18 + NDPChassis2715SA NDPChassisType = 20 + NDPChassis2486 NDPChassisType = 21 + NDPChassis28000series NDPChassisType = 22 + NDPChassis23000series NDPChassisType = 23 + NDPChassis5DN00xseries NDPChassisType = 24 + NDPChassisBayStackEthernet NDPChassisType = 25 + NDPChassis23100series NDPChassisType = 26 + NDPChassis100BaseTHub NDPChassisType = 27 + NDPChassis3000FastEthernet NDPChassisType = 28 + NDPChassisOrionSwitch NDPChassisType = 29 + NDPChassisDDS NDPChassisType = 31 + NDPChassisCentillion6slot NDPChassisType = 32 + NDPChassisCentillion12slot NDPChassisType = 33 + NDPChassisCentillion1slot NDPChassisType = 34 + NDPChassisBayStack301 NDPChassisType = 35 + NDPChassisBayStackTokenRingHub NDPChassisType = 36 + NDPChassisFVCMultimediaSwitch NDPChassisType = 37 + NDPChassisSwitchNode NDPChassisType = 38 + NDPChassisBayStack302Switch NDPChassisType = 39 + NDPChassisBayStack350Switch NDPChassisType = 40 + NDPChassisBayStack150EthernetHub NDPChassisType = 41 + NDPChassisCentillion50NSwitch NDPChassisType = 42 + NDPChassisCentillion50TSwitch NDPChassisType = 43 + NDPChassisBayStack303304Switches NDPChassisType = 44 + NDPChassisBayStack200EthernetHub NDPChassisType = 45 + NDPChassisBayStack25010100EthernetHub NDPChassisType = 46 + NDPChassisBayStack450101001000Switches NDPChassisType = 48 + NDPChassisBayStack41010100Switches NDPChassisType = 49 + NDPChassisPassport1200L3Switch NDPChassisType = 50 + NDPChassisPassport1250L3Switch NDPChassisType = 51 + NDPChassisPassport1100L3Switch NDPChassisType = 52 + NDPChassisPassport1150L3Switch NDPChassisType = 53 + NDPChassisPassport1050L3Switch NDPChassisType = 54 + NDPChassisPassport1051L3Switch NDPChassisType = 55 + NDPChassisPassport8610L3Switch NDPChassisType = 56 + NDPChassisPassport8606L3Switch NDPChassisType = 57 + NDPChassisPassport8010 NDPChassisType = 58 + NDPChassisPassport8006 NDPChassisType = 59 + NDPChassisBayStack670wirelessaccesspoint NDPChassisType = 60 + NDPChassisPassport740 NDPChassisType = 61 + NDPChassisPassport750 NDPChassisType = 62 + NDPChassisPassport790 NDPChassisType = 63 + NDPChassisBusinessPolicySwitch200010100Switches NDPChassisType = 64 + NDPChassisPassport8110L2Switch NDPChassisType = 65 + NDPChassisPassport8106L2Switch NDPChassisType = 66 + NDPChassisBayStack3580GigSwitch NDPChassisType = 67 + NDPChassisBayStack10PowerSupplyUnit NDPChassisType = 68 + NDPChassisBayStack42010100Switch NDPChassisType = 69 + NDPChassisOPTeraMetro1200EthernetServiceModule NDPChassisType = 70 + NDPChassisOPTera8010co NDPChassisType = 71 + NDPChassisOPTera8610coL3Switch NDPChassisType = 72 + NDPChassisOPTera8110coL2Switch NDPChassisType = 73 + NDPChassisOPTera8003 NDPChassisType = 74 + NDPChassisOPTera8603L3Switch NDPChassisType = 75 + NDPChassisOPTera8103L2Switch NDPChassisType = 76 + NDPChassisBayStack380101001000Switch NDPChassisType = 77 + NDPChassisEthernetSwitch47048T NDPChassisType = 78 + NDPChassisOPTeraMetro1450EthernetServiceModule NDPChassisType = 79 + NDPChassisOPTeraMetro1400EthernetServiceModule NDPChassisType = 80 + NDPChassisAlteonSwitchFamily NDPChassisType = 81 + NDPChassisEthernetSwitch46024TPWR NDPChassisType = 82 + NDPChassisOPTeraMetro8010OPML2Switch NDPChassisType = 83 + NDPChassisOPTeraMetro8010coOPML2Switch NDPChassisType = 84 + NDPChassisOPTeraMetro8006OPML2Switch NDPChassisType = 85 + NDPChassisOPTeraMetro8003OPML2Switch NDPChassisType = 86 + NDPChassisAlteon180e NDPChassisType = 87 + NDPChassisAlteonAD3 NDPChassisType = 88 + NDPChassisAlteon184 NDPChassisType = 89 + NDPChassisAlteonAD4 NDPChassisType = 90 + NDPChassisPassport1424L3Switch NDPChassisType = 91 + NDPChassisPassport1648L3Switch NDPChassisType = 92 + NDPChassisPassport1612L3Switch NDPChassisType = 93 + NDPChassisPassport1624L3Switch NDPChassisType = 94 + NDPChassisBayStack38024FFiber1000Switch NDPChassisType = 95 + NDPChassisEthernetRoutingSwitch551024T NDPChassisType = 96 + NDPChassisEthernetRoutingSwitch551048T NDPChassisType = 97 + NDPChassisEthernetSwitch47024T NDPChassisType = 98 + NDPChassisNortelNetworksWirelessLANAccessPoint2220 NDPChassisType = 99 + NDPChassisPassportRBS2402L3Switch NDPChassisType = 100 + NDPChassisAlteonApplicationSwitch2424 NDPChassisType = 101 + NDPChassisAlteonApplicationSwitch2224 NDPChassisType = 102 + NDPChassisAlteonApplicationSwitch2208 NDPChassisType = 103 + NDPChassisAlteonApplicationSwitch2216 NDPChassisType = 104 + NDPChassisAlteonApplicationSwitch3408 NDPChassisType = 105 + NDPChassisAlteonApplicationSwitch3416 NDPChassisType = 106 + NDPChassisNortelNetworksWirelessLANSecuritySwitch2250 NDPChassisType = 107 + NDPChassisEthernetSwitch42548T NDPChassisType = 108 + NDPChassisEthernetSwitch42524T NDPChassisType = 109 + NDPChassisNortelNetworksWirelessLANAccessPoint2221 NDPChassisType = 110 + NDPChassisNortelMetroEthernetServiceUnit24TSPFswitch NDPChassisType = 111 + NDPChassisNortelMetroEthernetServiceUnit24TLXDCswitch NDPChassisType = 112 + NDPChassisPassport830010slotchassis NDPChassisType = 113 + NDPChassisPassport83006slotchassis NDPChassisType = 114 + NDPChassisEthernetRoutingSwitch552024TPWR NDPChassisType = 115 + NDPChassisEthernetRoutingSwitch552048TPWR NDPChassisType = 116 + NDPChassisNortelNetworksVPNGateway3050 NDPChassisType = 117 + NDPChassisAlteonSSL31010100 NDPChassisType = 118 + NDPChassisAlteonSSL31010100Fiber NDPChassisType = 119 + NDPChassisAlteonSSL31010100FIPS NDPChassisType = 120 + NDPChassisAlteonSSL410101001000 NDPChassisType = 121 + NDPChassisAlteonSSL410101001000Fiber NDPChassisType = 122 + NDPChassisAlteonApplicationSwitch2424SSL NDPChassisType = 123 + NDPChassisEthernetSwitch32524T NDPChassisType = 124 + NDPChassisEthernetSwitch32524G NDPChassisType = 125 + NDPChassisNortelNetworksWirelessLANAccessPoint2225 NDPChassisType = 126 + NDPChassisNortelNetworksWirelessLANSecuritySwitch2270 NDPChassisType = 127 + NDPChassis24portEthernetSwitch47024TPWR NDPChassisType = 128 + NDPChassis48portEthernetSwitch47048TPWR NDPChassisType = 129 + NDPChassisEthernetRoutingSwitch553024TFD NDPChassisType = 130 + NDPChassisEthernetSwitch351024T NDPChassisType = 131 + NDPChassisNortelMetroEthernetServiceUnit12GACL3Switch NDPChassisType = 132 + NDPChassisNortelMetroEthernetServiceUnit12GDCL3Switch NDPChassisType = 133 + NDPChassisNortelSecureAccessSwitch NDPChassisType = 134 + NDPChassisNortelNetworksVPNGateway3070 NDPChassisType = 135 + NDPChassisOPTeraMetro3500 NDPChassisType = 136 + NDPChassisSMBBES101024T NDPChassisType = 137 + NDPChassisSMBBES101048T NDPChassisType = 138 + NDPChassisSMBBES102024TPWR NDPChassisType = 139 + NDPChassisSMBBES102048TPWR NDPChassisType = 140 + NDPChassisSMBBES201024T NDPChassisType = 141 + NDPChassisSMBBES201048T NDPChassisType = 142 + NDPChassisSMBBES202024TPWR NDPChassisType = 143 + NDPChassisSMBBES202048TPWR NDPChassisType = 144 + NDPChassisSMBBES11024T NDPChassisType = 145 + NDPChassisSMBBES11048T NDPChassisType = 146 + NDPChassisSMBBES12024TPWR NDPChassisType = 147 + NDPChassisSMBBES12048TPWR NDPChassisType = 148 + NDPChassisSMBBES21024T NDPChassisType = 149 + NDPChassisSMBBES21048T NDPChassisType = 150 + NDPChassisSMBBES22024TPWR NDPChassisType = 151 + NDPChassisSMBBES22048TPWR NDPChassisType = 152 + NDPChassisOME6500 NDPChassisType = 153 + NDPChassisEthernetRoutingSwitch4548GT NDPChassisType = 154 + NDPChassisEthernetRoutingSwitch4548GTPWR NDPChassisType = 155 + NDPChassisEthernetRoutingSwitch4550T NDPChassisType = 156 + NDPChassisEthernetRoutingSwitch4550TPWR NDPChassisType = 157 + NDPChassisEthernetRoutingSwitch4526FX NDPChassisType = 158 + NDPChassisEthernetRoutingSwitch250026T NDPChassisType = 159 + NDPChassisEthernetRoutingSwitch250026TPWR NDPChassisType = 160 + NDPChassisEthernetRoutingSwitch250050T NDPChassisType = 161 + NDPChassisEthernetRoutingSwitch250050TPWR NDPChassisType = 162 +) + +type NDPBackplaneType uint8 + +// Nortel Backplane Types +const ( + NDPBackplaneOther NDPBackplaneType = 1 + NDPBackplaneEthernet NDPBackplaneType = 2 + NDPBackplaneEthernetTokenring NDPBackplaneType = 3 + NDPBackplaneEthernetFDDI NDPBackplaneType = 4 + NDPBackplaneEthernetTokenringFDDI NDPBackplaneType = 5 + NDPBackplaneEthernetTokenringRedundantPower NDPBackplaneType = 6 + NDPBackplaneEthernetTokenringFDDIRedundantPower NDPBackplaneType = 7 + NDPBackplaneTokenRing NDPBackplaneType = 8 + NDPBackplaneEthernetTokenringFastEthernet NDPBackplaneType = 9 + NDPBackplaneEthernetFastEthernet NDPBackplaneType = 10 + NDPBackplaneEthernetTokenringFastEthernetRedundantPower NDPBackplaneType = 11 + NDPBackplaneEthernetFastEthernetGigabitEthernet NDPBackplaneType = 12 +) + +type NDPState uint8 + +// Device State +const ( + NDPStateTopology NDPState = 1 + NDPStateHeartbeat NDPState = 2 + NDPStateNew NDPState = 3 +) + +// NortelDiscovery is a packet layer containing the Nortel Discovery Protocol. +type NortelDiscovery struct { + BaseLayer + IPAddress net.IP + SegmentID []byte + Chassis NDPChassisType + Backplane NDPBackplaneType + State NDPState + NumLinks uint8 +} + +// LayerType returns gopacket.LayerTypeNortelDiscovery. +func (c *NortelDiscovery) LayerType() gopacket.LayerType { + return LayerTypeNortelDiscovery +} + +func decodeNortelDiscovery(data []byte, p gopacket.PacketBuilder) error { + c := &NortelDiscovery{} + if len(data) < 11 { + return fmt.Errorf("Invalid NortelDiscovery packet length %d", len(data)) + } + c.IPAddress = data[0:4] + c.SegmentID = data[4:7] + c.Chassis = NDPChassisType(data[7]) + c.Backplane = NDPBackplaneType(data[8]) + c.State = NDPState(data[9]) + c.NumLinks = uint8(data[10]) + p.AddLayer(c) + return nil +} + +func (t NDPChassisType) String() (s string) { + switch t { + case NDPChassisother: + s = "other" + case NDPChassis3000: + s = "3000" + case NDPChassis3030: + s = "3030" + case NDPChassis2310: + s = "2310" + case NDPChassis2810: + s = "2810" + case NDPChassis2912: + s = "2912" + case NDPChassis2914: + s = "2914" + case NDPChassis271x: + s = "271x" + case NDPChassis2813: + s = "2813" + case NDPChassis2814: + s = "2814" + case NDPChassis2915: + s = "2915" + case NDPChassis5000: + s = "5000" + case NDPChassis2813SA: + s = "2813SA" + case NDPChassis2814SA: + s = "2814SA" + case NDPChassis810M: + s = "810M" + case NDPChassisEthercell: + s = "Ethercell" + case NDPChassis5005: + s = "5005" + case NDPChassisAlcatelEWC: + s = "Alcatel Ethernet workgroup conc." + case NDPChassis2715SA: + s = "2715SA" + case NDPChassis2486: + s = "2486" + case NDPChassis28000series: + s = "28000 series" + case NDPChassis23000series: + s = "23000 series" + case NDPChassis5DN00xseries: + s = "5DN00x series" + case NDPChassisBayStackEthernet: + s = "BayStack Ethernet" + case NDPChassis23100series: + s = "23100 series" + case NDPChassis100BaseTHub: + s = "100Base-T Hub" + case NDPChassis3000FastEthernet: + s = "3000 Fast Ethernet" + case NDPChassisOrionSwitch: + s = "Orion switch" + case NDPChassisDDS: + s = "DDS" + case NDPChassisCentillion6slot: + s = "Centillion (6 slot)" + case NDPChassisCentillion12slot: + s = "Centillion (12 slot)" + case NDPChassisCentillion1slot: + s = "Centillion (1 slot)" + case NDPChassisBayStack301: + s = "BayStack 301" + case NDPChassisBayStackTokenRingHub: + s = "BayStack TokenRing Hub" + case NDPChassisFVCMultimediaSwitch: + s = "FVC Multimedia Switch" + case NDPChassisSwitchNode: + s = "Switch Node" + case NDPChassisBayStack302Switch: + s = "BayStack 302 Switch" + case NDPChassisBayStack350Switch: + s = "BayStack 350 Switch" + case NDPChassisBayStack150EthernetHub: + s = "BayStack 150 Ethernet Hub" + case NDPChassisCentillion50NSwitch: + s = "Centillion 50N switch" + case NDPChassisCentillion50TSwitch: + s = "Centillion 50T switch" + case NDPChassisBayStack303304Switches: + s = "BayStack 303 and 304 Switches" + case NDPChassisBayStack200EthernetHub: + s = "BayStack 200 Ethernet Hub" + case NDPChassisBayStack25010100EthernetHub: + s = "BayStack 250 10/100 Ethernet Hub" + case NDPChassisBayStack450101001000Switches: + s = "BayStack 450 10/100/1000 Switches" + case NDPChassisBayStack41010100Switches: + s = "BayStack 410 10/100 Switches" + case NDPChassisPassport1200L3Switch: + s = "Passport 1200 L3 Switch" + case NDPChassisPassport1250L3Switch: + s = "Passport 1250 L3 Switch" + case NDPChassisPassport1100L3Switch: + s = "Passport 1100 L3 Switch" + case NDPChassisPassport1150L3Switch: + s = "Passport 1150 L3 Switch" + case NDPChassisPassport1050L3Switch: + s = "Passport 1050 L3 Switch" + case NDPChassisPassport1051L3Switch: + s = "Passport 1051 L3 Switch" + case NDPChassisPassport8610L3Switch: + s = "Passport 8610 L3 Switch" + case NDPChassisPassport8606L3Switch: + s = "Passport 8606 L3 Switch" + case NDPChassisPassport8010: + s = "Passport 8010" + case NDPChassisPassport8006: + s = "Passport 8006" + case NDPChassisBayStack670wirelessaccesspoint: + s = "BayStack 670 wireless access point" + case NDPChassisPassport740: + s = "Passport 740" + case NDPChassisPassport750: + s = "Passport 750" + case NDPChassisPassport790: + s = "Passport 790" + case NDPChassisBusinessPolicySwitch200010100Switches: + s = "Business Policy Switch 2000 10/100 Switches" + case NDPChassisPassport8110L2Switch: + s = "Passport 8110 L2 Switch" + case NDPChassisPassport8106L2Switch: + s = "Passport 8106 L2 Switch" + case NDPChassisBayStack3580GigSwitch: + s = "BayStack 3580 Gig Switch" + case NDPChassisBayStack10PowerSupplyUnit: + s = "BayStack 10 Power Supply Unit" + case NDPChassisBayStack42010100Switch: + s = "BayStack 420 10/100 Switch" + case NDPChassisOPTeraMetro1200EthernetServiceModule: + s = "OPTera Metro 1200 Ethernet Service Module" + case NDPChassisOPTera8010co: + s = "OPTera 8010co" + case NDPChassisOPTera8610coL3Switch: + s = "OPTera 8610co L3 switch" + case NDPChassisOPTera8110coL2Switch: + s = "OPTera 8110co L2 switch" + case NDPChassisOPTera8003: + s = "OPTera 8003" + case NDPChassisOPTera8603L3Switch: + s = "OPTera 8603 L3 switch" + case NDPChassisOPTera8103L2Switch: + s = "OPTera 8103 L2 switch" + case NDPChassisBayStack380101001000Switch: + s = "BayStack 380 10/100/1000 Switch" + case NDPChassisEthernetSwitch47048T: + s = "Ethernet Switch 470-48T" + case NDPChassisOPTeraMetro1450EthernetServiceModule: + s = "OPTera Metro 1450 Ethernet Service Module" + case NDPChassisOPTeraMetro1400EthernetServiceModule: + s = "OPTera Metro 1400 Ethernet Service Module" + case NDPChassisAlteonSwitchFamily: + s = "Alteon Switch Family" + case NDPChassisEthernetSwitch46024TPWR: + s = "Ethernet Switch 460-24T-PWR" + case NDPChassisOPTeraMetro8010OPML2Switch: + s = "OPTera Metro 8010 OPM L2 Switch" + case NDPChassisOPTeraMetro8010coOPML2Switch: + s = "OPTera Metro 8010co OPM L2 Switch" + case NDPChassisOPTeraMetro8006OPML2Switch: + s = "OPTera Metro 8006 OPM L2 Switch" + case NDPChassisOPTeraMetro8003OPML2Switch: + s = "OPTera Metro 8003 OPM L2 Switch" + case NDPChassisAlteon180e: + s = "Alteon 180e" + case NDPChassisAlteonAD3: + s = "Alteon AD3" + case NDPChassisAlteon184: + s = "Alteon 184" + case NDPChassisAlteonAD4: + s = "Alteon AD4" + case NDPChassisPassport1424L3Switch: + s = "Passport 1424 L3 switch" + case NDPChassisPassport1648L3Switch: + s = "Passport 1648 L3 switch" + case NDPChassisPassport1612L3Switch: + s = "Passport 1612 L3 switch" + case NDPChassisPassport1624L3Switch: + s = "Passport 1624 L3 switch" + case NDPChassisBayStack38024FFiber1000Switch: + s = "BayStack 380-24F Fiber 1000 Switch" + case NDPChassisEthernetRoutingSwitch551024T: + s = "Ethernet Routing Switch 5510-24T" + case NDPChassisEthernetRoutingSwitch551048T: + s = "Ethernet Routing Switch 5510-48T" + case NDPChassisEthernetSwitch47024T: + s = "Ethernet Switch 470-24T" + case NDPChassisNortelNetworksWirelessLANAccessPoint2220: + s = "Nortel Networks Wireless LAN Access Point 2220" + case NDPChassisPassportRBS2402L3Switch: + s = "Passport RBS 2402 L3 switch" + case NDPChassisAlteonApplicationSwitch2424: + s = "Alteon Application Switch 2424" + case NDPChassisAlteonApplicationSwitch2224: + s = "Alteon Application Switch 2224" + case NDPChassisAlteonApplicationSwitch2208: + s = "Alteon Application Switch 2208" + case NDPChassisAlteonApplicationSwitch2216: + s = "Alteon Application Switch 2216" + case NDPChassisAlteonApplicationSwitch3408: + s = "Alteon Application Switch 3408" + case NDPChassisAlteonApplicationSwitch3416: + s = "Alteon Application Switch 3416" + case NDPChassisNortelNetworksWirelessLANSecuritySwitch2250: + s = "Nortel Networks Wireless LAN SecuritySwitch 2250" + case NDPChassisEthernetSwitch42548T: + s = "Ethernet Switch 425-48T" + case NDPChassisEthernetSwitch42524T: + s = "Ethernet Switch 425-24T" + case NDPChassisNortelNetworksWirelessLANAccessPoint2221: + s = "Nortel Networks Wireless LAN Access Point 2221" + case NDPChassisNortelMetroEthernetServiceUnit24TSPFswitch: + s = "Nortel Metro Ethernet Service Unit 24-T SPF switch" + case NDPChassisNortelMetroEthernetServiceUnit24TLXDCswitch: + s = " Nortel Metro Ethernet Service Unit 24-T LX DC switch" + case NDPChassisPassport830010slotchassis: + s = "Passport 8300 10-slot chassis" + case NDPChassisPassport83006slotchassis: + s = "Passport 8300 6-slot chassis" + case NDPChassisEthernetRoutingSwitch552024TPWR: + s = "Ethernet Routing Switch 5520-24T-PWR" + case NDPChassisEthernetRoutingSwitch552048TPWR: + s = "Ethernet Routing Switch 5520-48T-PWR" + case NDPChassisNortelNetworksVPNGateway3050: + s = "Nortel Networks VPN Gateway 3050" + case NDPChassisAlteonSSL31010100: + s = "Alteon SSL 310 10/100" + case NDPChassisAlteonSSL31010100Fiber: + s = "Alteon SSL 310 10/100 Fiber" + case NDPChassisAlteonSSL31010100FIPS: + s = "Alteon SSL 310 10/100 FIPS" + case NDPChassisAlteonSSL410101001000: + s = "Alteon SSL 410 10/100/1000" + case NDPChassisAlteonSSL410101001000Fiber: + s = "Alteon SSL 410 10/100/1000 Fiber" + case NDPChassisAlteonApplicationSwitch2424SSL: + s = "Alteon Application Switch 2424-SSL" + case NDPChassisEthernetSwitch32524T: + s = "Ethernet Switch 325-24T" + case NDPChassisEthernetSwitch32524G: + s = "Ethernet Switch 325-24G" + case NDPChassisNortelNetworksWirelessLANAccessPoint2225: + s = "Nortel Networks Wireless LAN Access Point 2225" + case NDPChassisNortelNetworksWirelessLANSecuritySwitch2270: + s = "Nortel Networks Wireless LAN SecuritySwitch 2270" + case NDPChassis24portEthernetSwitch47024TPWR: + s = "24-port Ethernet Switch 470-24T-PWR" + case NDPChassis48portEthernetSwitch47048TPWR: + s = "48-port Ethernet Switch 470-48T-PWR" + case NDPChassisEthernetRoutingSwitch553024TFD: + s = "Ethernet Routing Switch 5530-24TFD" + case NDPChassisEthernetSwitch351024T: + s = "Ethernet Switch 3510-24T" + case NDPChassisNortelMetroEthernetServiceUnit12GACL3Switch: + s = "Nortel Metro Ethernet Service Unit 12G AC L3 switch" + case NDPChassisNortelMetroEthernetServiceUnit12GDCL3Switch: + s = "Nortel Metro Ethernet Service Unit 12G DC L3 switch" + case NDPChassisNortelSecureAccessSwitch: + s = "Nortel Secure Access Switch" + case NDPChassisNortelNetworksVPNGateway3070: + s = "Nortel Networks VPN Gateway 3070" + case NDPChassisOPTeraMetro3500: + s = "OPTera Metro 3500" + case NDPChassisSMBBES101024T: + s = "SMB BES 1010 24T" + case NDPChassisSMBBES101048T: + s = "SMB BES 1010 48T" + case NDPChassisSMBBES102024TPWR: + s = "SMB BES 1020 24T PWR" + case NDPChassisSMBBES102048TPWR: + s = "SMB BES 1020 48T PWR" + case NDPChassisSMBBES201024T: + s = "SMB BES 2010 24T" + case NDPChassisSMBBES201048T: + s = "SMB BES 2010 48T" + case NDPChassisSMBBES202024TPWR: + s = "SMB BES 2020 24T PWR" + case NDPChassisSMBBES202048TPWR: + s = "SMB BES 2020 48T PWR" + case NDPChassisSMBBES11024T: + s = "SMB BES 110 24T" + case NDPChassisSMBBES11048T: + s = "SMB BES 110 48T" + case NDPChassisSMBBES12024TPWR: + s = "SMB BES 120 24T PWR" + case NDPChassisSMBBES12048TPWR: + s = "SMB BES 120 48T PWR" + case NDPChassisSMBBES21024T: + s = "SMB BES 210 24T" + case NDPChassisSMBBES21048T: + s = "SMB BES 210 48T" + case NDPChassisSMBBES22024TPWR: + s = "SMB BES 220 24T PWR" + case NDPChassisSMBBES22048TPWR: + s = "SMB BES 220 48T PWR" + case NDPChassisOME6500: + s = "OME 6500" + case NDPChassisEthernetRoutingSwitch4548GT: + s = "Ethernet Routing Switch 4548GT" + case NDPChassisEthernetRoutingSwitch4548GTPWR: + s = "Ethernet Routing Switch 4548GT-PWR" + case NDPChassisEthernetRoutingSwitch4550T: + s = "Ethernet Routing Switch 4550T" + case NDPChassisEthernetRoutingSwitch4550TPWR: + s = "Ethernet Routing Switch 4550T-PWR" + case NDPChassisEthernetRoutingSwitch4526FX: + s = "Ethernet Routing Switch 4526FX" + case NDPChassisEthernetRoutingSwitch250026T: + s = "Ethernet Routing Switch 2500-26T" + case NDPChassisEthernetRoutingSwitch250026TPWR: + s = "Ethernet Routing Switch 2500-26T-PWR" + case NDPChassisEthernetRoutingSwitch250050T: + s = "Ethernet Routing Switch 2500-50T" + case NDPChassisEthernetRoutingSwitch250050TPWR: + s = "Ethernet Routing Switch 2500-50T-PWR" + default: + s = "Unknown" + } + return +} + +func (t NDPBackplaneType) String() (s string) { + switch t { + case NDPBackplaneOther: + s = "Other" + case NDPBackplaneEthernet: + s = "Ethernet" + case NDPBackplaneEthernetTokenring: + s = "Ethernet and Tokenring" + case NDPBackplaneEthernetFDDI: + s = "Ethernet and FDDI" + case NDPBackplaneEthernetTokenringFDDI: + s = "Ethernet, Tokenring and FDDI" + case NDPBackplaneEthernetTokenringRedundantPower: + s = "Ethernet and Tokenring with redundant power" + case NDPBackplaneEthernetTokenringFDDIRedundantPower: + s = "Ethernet, Tokenring, FDDI with redundant power" + case NDPBackplaneTokenRing: + s = "Token Ring" + case NDPBackplaneEthernetTokenringFastEthernet: + s = "Ethernet, Tokenring and Fast Ethernet" + case NDPBackplaneEthernetFastEthernet: + s = "Ethernet and Fast Ethernet" + case NDPBackplaneEthernetTokenringFastEthernetRedundantPower: + s = "Ethernet, Tokenring, Fast Ethernet with redundant power" + case NDPBackplaneEthernetFastEthernetGigabitEthernet: + s = "Ethernet, Fast Ethernet and Gigabit Ethernet" + default: + s = "Unknown" + } + return +} + +func (t NDPState) String() (s string) { + switch t { + case NDPStateTopology: + s = "Topology Change" + case NDPStateHeartbeat: + s = "Heartbeat" + case NDPStateNew: + s = "New" + default: + s = "Unknown" + } + return +} diff --git a/vendor/github.com/google/gopacket/layers/ntp.go b/vendor/github.com/google/gopacket/layers/ntp.go new file mode 100644 index 0000000..33c15b3 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/ntp.go @@ -0,0 +1,416 @@ +// Copyright 2016 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. +// +//****************************************************************************** + +package layers + +import ( + "encoding/binary" + "errors" + + "github.com/google/gopacket" +) + +//****************************************************************************** +// +// Network Time Protocol (NTP) Decoding Layer +// ------------------------------------------ +// This file provides a GoPacket decoding layer for NTP. +// +//****************************************************************************** +// +// About The Network Time Protocol (NTP) +// ------------------------------------- +// NTP is a protocol that enables computers on the internet to set their +// clocks to the correct time (or to a time that is acceptably close to the +// correct time). NTP runs on top of UDP. +// +// There have been a series of versions of the NTP protocol. The latest +// version is V4 and is specified in RFC 5905: +// http://www.ietf.org/rfc/rfc5905.txt +// +//****************************************************************************** +// +// References +// ---------- +// +// Wikipedia's NTP entry: +// https://en.wikipedia.org/wiki/Network_Time_Protocol +// This is the best place to get an overview of NTP. +// +// Network Time Protocol Home Website: +// http://www.ntp.org/ +// This appears to be the official website of NTP. +// +// List of current NTP Protocol RFCs: +// http://www.ntp.org/rfc.html +// +// RFC 958: "Network Time Protocol (NTP)" (1985) +// https://tools.ietf.org/html/rfc958 +// This is the original NTP specification. +// +// RFC 1305: "Network Time Protocol (Version 3) Specification, Implementation and Analysis" (1992) +// https://tools.ietf.org/html/rfc1305 +// The protocol was updated in 1992 yielding NTP V3. +// +// RFC 5905: "Network Time Protocol Version 4: Protocol and Algorithms Specification" (2010) +// https://www.ietf.org/rfc/rfc5905.txt +// The protocol was updated in 2010 yielding NTP V4. +// V4 is backwards compatible with all previous versions of NTP. +// +// RFC 5906: "Network Time Protocol Version 4: Autokey Specification" +// https://tools.ietf.org/html/rfc5906 +// This document addresses the security of the NTP protocol +// and is probably not relevant to this package. +// +// RFC 5907: "Definitions of Managed Objects for Network Time Protocol Version 4 (NTPv4)" +// https://tools.ietf.org/html/rfc5907 +// This document addresses the management of NTP servers and +// is probably not relevant to this package. +// +// RFC 5908: "Network Time Protocol (NTP) Server Option for DHCPv6" +// https://tools.ietf.org/html/rfc5908 +// This document addresses the use of NTP in DHCPv6 and is +// probably not relevant to this package. +// +// "Let's make a NTP Client in C" +// https://lettier.github.io/posts/2016-04-26-lets-make-a-ntp-client-in-c.html +// This web page contains useful information about the details of NTP, +// including an NTP record struture in C, and C code. +// +// "NTP Packet Header (NTP Reference Implementation) (Computer Network Time Synchronization)" +// http://what-when-how.com/computer-network-time-synchronization/ +// ntp-packet-header-ntp-reference-implementation-computer-network-time-synchronization/ +// This web page contains useful information on the details of NTP. +// +// "Technical information - NTP Data Packet" +// https://www.meinbergglobal.com/english/info/ntp-packet.htm +// This page has a helpful diagram of an NTP V4 packet. +// +//****************************************************************************** +// +// Obsolete References +// ------------------- +// +// RFC 1119: "RFC-1119 "Network Time Protocol (Version 2) Specification and Implementation" (1989) +// https://tools.ietf.org/html/rfc1119 +// Version 2 was drafted in 1989. +// It is unclear whether V2 was ever implememented or whether the +// ideas ended up in V3 (which was implemented in 1992). +// +// RFC 1361: "Simple Network Time Protocol (SNTP)" +// https://tools.ietf.org/html/rfc1361 +// This document is obsoleted by RFC 1769 and is included only for completeness. +// +// RFC 1769: "Simple Network Time Protocol (SNTP)" +// https://tools.ietf.org/html/rfc1769 +// This document is obsoleted by RFC 2030 and RFC 4330 and is included only for completeness. +// +// RFC 2030: "Simple Network Time Protocol (SNTP) Version 4 for IPv4, IPv6 and OSI" +// https://tools.ietf.org/html/rfc2030 +// This document is obsoleted by RFC 4330 and is included only for completeness. +// +// RFC 4330: "Simple Network Time Protocol (SNTP) Version 4 for IPv4, IPv6 and OSI" +// https://tools.ietf.org/html/rfc4330 +// This document is obsoleted by RFC 5905 and is included only for completeness. +// +//****************************************************************************** +// +// Endian And Bit Numbering Issues +// ------------------------------- +// +// Endian and bit numbering issues can be confusing. Here is some +// clarification: +// +// ENDIAN: Values are sent big endian. +// https://en.wikipedia.org/wiki/Endianness +// +// BIT NUMBERING: Bits are numbered 0 upwards from the most significant +// bit to the least significant bit. This means that if there is a 32-bit +// value, the most significant bit is called bit 0 and the least +// significant bit is called bit 31. +// +// See RFC 791 Appendix B for more discussion. +// +//****************************************************************************** +// +// NTP V3 and V4 Packet Format +// --------------------------- +// NTP packets are UDP packets whose payload contains an NTP record. +// +// The NTP RFC defines the format of the NTP record. +// +// There have been four versions of the protocol: +// +// V1 in 1985 +// V2 in 1989 +// V3 in 1992 +// V4 in 2010 +// +// It is clear that V1 and V2 are obsolete, and there is no need to +// cater for these formats. +// +// V3 and V4 essentially use the same format, with V4 adding some optional +// fields on the end. So this package supports the V3 and V4 formats. +// +// The current version of NTP (NTP V4)'s RFC (V4 - RFC 5905) contains +// the following diagram for the NTP record format: + +// 0 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// |LI | VN |Mode | Stratum | Poll | Precision | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Root Delay | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Root Dispersion | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Reference ID | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | | +// + Reference Timestamp (64) + +// | | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | | +// + Origin Timestamp (64) + +// | | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | | +// + Receive Timestamp (64) + +// | | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | | +// + Transmit Timestamp (64) + +// | | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | | +// . . +// . Extension Field 1 (variable) . +// . . +// | | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | | +// . . +// . Extension Field 2 (variable) . +// . . +// | | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Key Identifier | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | | +// | dgst (128) | +// | | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// From http://www.ietf.org/rfc/rfc5905.txt +// +// The fields "Extension Field 1 (variable)" and later are optional fields, +// and so we can set a minimum NTP record size of 48 bytes. +// +const ntpMinimumRecordSizeInBytes int = 48 + +//****************************************************************************** + +// NTP Type +// -------- +// Type NTP implements the DecodingLayer interface. Each NTP object +// represents in a structured form the NTP record present as the UDP +// payload in an NTP UDP packet. +// + +type NTPLeapIndicator uint8 +type NTPVersion uint8 +type NTPMode uint8 +type NTPStratum uint8 +type NTPLog2Seconds int8 +type NTPFixed16Seconds uint32 +type NTPReferenceID uint32 +type NTPTimestamp uint64 + +type NTP struct { + BaseLayer // Stores the packet bytes and payload bytes. + + LeapIndicator NTPLeapIndicator // [0,3]. Indicates whether leap second(s) is to be added. + Version NTPVersion // [0,7]. Version of the NTP protocol. + Mode NTPMode // [0,7]. Mode. + Stratum NTPStratum // [0,255]. Stratum of time server in the server tree. + Poll NTPLog2Seconds // [-128,127]. The maximum interval between successive messages, in log2 seconds. + Precision NTPLog2Seconds // [-128,127]. The precision of the system clock, in log2 seconds. + RootDelay NTPFixed16Seconds // [0,2^32-1]. Total round trip delay to the reference clock in seconds times 2^16. + RootDispersion NTPFixed16Seconds // [0,2^32-1]. Total dispersion to the reference clock, in seconds times 2^16. + ReferenceID NTPReferenceID // ID code of reference clock [0,2^32-1]. + ReferenceTimestamp NTPTimestamp // Most recent timestamp from the reference clock. + OriginTimestamp NTPTimestamp // Local time when request was sent from local host. + ReceiveTimestamp NTPTimestamp // Local time (on server) that request arrived at server host. + TransmitTimestamp NTPTimestamp // Local time (on server) that request departed server host. + + // FIX: This package should analyse the extension fields and represent the extension fields too. + ExtensionBytes []byte // Just put extensions in a byte slice. +} + +//****************************************************************************** + +// LayerType returns the layer type of the NTP object, which is LayerTypeNTP. +func (d *NTP) LayerType() gopacket.LayerType { + return LayerTypeNTP +} + +//****************************************************************************** + +// decodeNTP analyses a byte slice and attempts to decode it as an NTP +// record of a UDP packet. +// +// If it succeeds, it loads p with information about the packet and returns nil. +// If it fails, it returns an error (non nil). +// +// This function is employed in layertypes.go to register the NTP layer. +func decodeNTP(data []byte, p gopacket.PacketBuilder) error { + + // Attempt to decode the byte slice. + d := &NTP{} + err := d.DecodeFromBytes(data, p) + if err != nil { + return err + } + + // If the decoding worked, add the layer to the packet and set it + // as the application layer too, if there isn't already one. + p.AddLayer(d) + p.SetApplicationLayer(d) + + return nil +} + +//****************************************************************************** + +// DecodeFromBytes analyses a byte slice and attempts to decode it as an NTP +// record of a UDP packet. +// +// Upon succeeds, it loads the NTP object with information about the packet +// and returns nil. +// Upon failure, it returns an error (non nil). +func (d *NTP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + + // If the data block is too short to be a NTP record, then return an error. + if len(data) < ntpMinimumRecordSizeInBytes { + df.SetTruncated() + return errors.New("NTP packet too short") + } + + // RFC 5905 does not appear to define a maximum NTP record length. + // The protocol allows "extension fields" to be included in the record, + // and states about these fields:" + // + // "While the minimum field length containing required fields is + // four words (16 octets), a maximum field length remains to be + // established." + // + // For this reason, the packet length is not checked here for being too long. + + // NTP type embeds type BaseLayer which contains two fields: + // Contents is supposed to contain the bytes of the data at this level. + // Payload is supposed to contain the payload of this level. + // Here we set the baselayer to be the bytes of the NTP record. + d.BaseLayer = BaseLayer{Contents: data[:len(data)]} + + // Extract the fields from the block of bytes. + // To make sense of this, refer to the packet diagram + // above and the section on endian conventions. + + // The first few fields are all packed into the first 32 bits. Unpack them. + f := data[0] + d.LeapIndicator = NTPLeapIndicator((f & 0xC0) >> 6) + d.Version = NTPVersion((f & 0x38) >> 3) + d.Mode = NTPMode(f & 0x07) + d.Stratum = NTPStratum(data[1]) + d.Poll = NTPLog2Seconds(data[2]) + d.Precision = NTPLog2Seconds(data[3]) + + // The remaining fields can just be copied in big endian order. + d.RootDelay = NTPFixed16Seconds(binary.BigEndian.Uint32(data[4:8])) + d.RootDispersion = NTPFixed16Seconds(binary.BigEndian.Uint32(data[8:12])) + d.ReferenceID = NTPReferenceID(binary.BigEndian.Uint32(data[12:16])) + d.ReferenceTimestamp = NTPTimestamp(binary.BigEndian.Uint64(data[16:24])) + d.OriginTimestamp = NTPTimestamp(binary.BigEndian.Uint64(data[24:32])) + d.ReceiveTimestamp = NTPTimestamp(binary.BigEndian.Uint64(data[32:40])) + d.TransmitTimestamp = NTPTimestamp(binary.BigEndian.Uint64(data[40:48])) + + // This layer does not attempt to analyse the extension bytes. + // But if there are any, we'd like the user to know. So we just + // place them all in an ExtensionBytes field. + d.ExtensionBytes = data[48:] + + // Return no error. + return nil +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (d *NTP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + data, err := b.PrependBytes(ntpMinimumRecordSizeInBytes) + if err != nil { + return err + } + + // Pack the first few fields into the first 32 bits. + h := uint8(0) + h |= (uint8(d.LeapIndicator) << 6) & 0xC0 + h |= (uint8(d.Version) << 3) & 0x38 + h |= (uint8(d.Mode)) & 0x07 + data[0] = byte(h) + data[1] = byte(d.Stratum) + data[2] = byte(d.Poll) + data[3] = byte(d.Precision) + + // The remaining fields can just be copied in big endian order. + binary.BigEndian.PutUint32(data[4:8], uint32(d.RootDelay)) + binary.BigEndian.PutUint32(data[8:12], uint32(d.RootDispersion)) + binary.BigEndian.PutUint32(data[12:16], uint32(d.ReferenceID)) + binary.BigEndian.PutUint64(data[16:24], uint64(d.ReferenceTimestamp)) + binary.BigEndian.PutUint64(data[24:32], uint64(d.OriginTimestamp)) + binary.BigEndian.PutUint64(data[32:40], uint64(d.ReceiveTimestamp)) + binary.BigEndian.PutUint64(data[40:48], uint64(d.TransmitTimestamp)) + + ex, err := b.AppendBytes(len(d.ExtensionBytes)) + if err != nil { + return err + } + copy(ex, d.ExtensionBytes) + + return nil +} + +//****************************************************************************** + +// CanDecode returns a set of layers that NTP objects can decode. +// As NTP objects can only decide the NTP layer, we can return just that layer. +// Apparently a single layer type implements LayerClass. +func (d *NTP) CanDecode() gopacket.LayerClass { + return LayerTypeNTP +} + +//****************************************************************************** + +// NextLayerType specifies the next layer that GoPacket should attempt to +// analyse after this (NTP) layer. As NTP packets do not contain any payload +// bytes, there are no further layers to analyse. +func (d *NTP) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypeZero +} + +//****************************************************************************** + +// NTP packets do not carry any data payload, so the empty byte slice is retured. +// In Go, a nil slice is functionally identical to an empty slice, so we +// return nil to avoid a heap allocation. +func (d *NTP) Payload() []byte { + return nil +} + +//****************************************************************************** +//* End Of NTP File * +//****************************************************************************** diff --git a/vendor/github.com/google/gopacket/layers/ntp_test.go b/vendor/github.com/google/gopacket/layers/ntp_test.go new file mode 100644 index 0000000..b522216 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/ntp_test.go @@ -0,0 +1,258 @@ +// Copyright 2016 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. +// +//****************************************************************************** + +package layers + +import ( + "crypto/rand" + "github.com/google/gopacket" + "io" + "reflect" + "testing" +) + +//****************************************************************************** + +// checkNTP() uses the ntp.go code to analyse the packet bytes as an NTP UDP +// packet and generate an NTP object. It then compares the generated NTP object +// with the one provided and throws an error if there is any difference. +// The desc argument is output with any failure message to identify the test. +func checkNTP(desc string, t *testing.T, packetBytes []byte, pExpectedNTP *NTP) { + + // Analyse the packet bytes, yielding a new packet object p. + p := gopacket.NewPacket(packetBytes, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Errorf("Failed to decode packet %s: %v", desc, p.ErrorLayer().Error()) + } + + // Ensure that the packet analysis yielded the correct set of layers: + // Link Layer = Ethernet. + // Network Layer = IPv4. + // Transport Layer = UDP. + // Application Layer = NTP. + checkLayers(p, []gopacket.LayerType{ + LayerTypeEthernet, + LayerTypeIPv4, + LayerTypeUDP, + LayerTypeNTP}, t) + + // Select the Application (NTP) layer. + pResultNTP, ok := p.ApplicationLayer().(*NTP) + if !ok { + t.Error("No NTP layer type found in packet in " + desc + ".") + } + + // Compare the generated NTP object with the expected NTP object. + if !reflect.DeepEqual(pResultNTP, pExpectedNTP) { + t.Errorf("NTP packet processing failed for packet "+desc+ + ":\ngot :\n%#v\n\nwant :\n%#v\n\n", pResultNTP, pExpectedNTP) + } + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{} + err := pResultNTP.SerializeTo(buf, opts) + if err != nil { + t.Error(err) + } + if !reflect.DeepEqual(pResultNTP.BaseLayer.Contents, buf.Bytes()) { + t.Errorf("NTP packet serialization failed for packet "+desc+ + ":\ngot :\n%x\n\nwant :\n%x\n\n", buf.Bytes(), packetBytes) + } +} + +//****************************************************************************** + +func TestNTPOne(t *testing.T) { + + // This test packet is the first NTP packet in the NTP sample capture + // pcap file NTP_sync.pcap on the Wireshark sample captures page: + // + // https://wiki.wireshark.org/SampleCaptures + // https://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=get&target=NTP_sync.pcap + var testPacketNTP = []byte{ + 0x00, 0x0c, 0x41, 0x82, 0xb2, 0x53, 0x00, 0xd0, + 0x59, 0x6c, 0x40, 0x4e, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x4c, 0x0a, 0x42, 0x00, 0x00, 0x80, 0x11, + 0xb5, 0xfa, 0xc0, 0xa8, 0x32, 0x32, 0x43, 0x81, + 0x44, 0x09, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x38, + 0xf8, 0xd2, 0xd9, 0x00, 0x0a, 0xfa, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x02, 0x90, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc5, 0x02, 0x04, 0xec, 0xec, 0x42, + 0xee, 0x92, + } + + // Assemble the NTP object that we expect to emerge from this test. + pExpectedNTP := &NTP{ + BaseLayer: BaseLayer{ + Contents: []byte{0xd9, 0x0, 0xa, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x2, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc5, 0x2, 0x4, 0xec, 0xec, 0x42, 0xee, 0x92}, + Payload: nil, + }, + LeapIndicator: 3, + Version: 3, + Mode: 1, + Stratum: 0, + Poll: 10, + Precision: -6, + RootDelay: 0, + RootDispersion: 0x10290, + ReferenceID: 0, + ReferenceTimestamp: 0, + OriginTimestamp: 0, + ReceiveTimestamp: 0, + TransmitTimestamp: 0xc50204ecec42ee92, + ExtensionBytes: []byte{}, + } + + checkNTP("test01", t, testPacketNTP, pExpectedNTP) +} + +//****************************************************************************** + +func TestNTPTwo(t *testing.T) { + + // This test packet is packet #18 in the NTP sample capture + // pcap file NTP_sync.pcap on the Wireshark sample captures page: + // + // https://wiki.wireshark.org/SampleCaptures + // https://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=get&target=NTP_sync.pcap + // + // This packet was chosen because it is the first NTP packet after the first + // NTP packet that has non-zero timestamps. + + var testPacketNTP = []byte{ + 0x00, 0xd0, 0x59, 0x6c, 0x40, 0x4e, 0x00, 0x0c, + 0x41, 0x82, 0xb2, 0x53, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x4c, 0x32, 0x46, 0x40, 0x00, 0x2f, 0x11, + 0xa8, 0x18, 0x45, 0x2c, 0x39, 0x3c, 0xc0, 0xa8, + 0x32, 0x32, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x38, + 0x09, 0x58, 0x1a, 0x03, 0x0a, 0xee, 0x00, 0x00, + 0x1b, 0xf7, 0x00, 0x00, 0x14, 0xec, 0x51, 0xae, + 0x80, 0xb7, 0xc5, 0x02, 0x03, 0x4c, 0x8d, 0x0e, + 0x66, 0xcb, 0xc5, 0x02, 0x04, 0xec, 0xec, 0x42, + 0xee, 0x92, 0xc5, 0x02, 0x04, 0xeb, 0xcf, 0x49, + 0x59, 0xe6, 0xc5, 0x02, 0x04, 0xeb, 0xcf, 0x4c, + 0x6e, 0x6e, + } + + // Assemble the NTP object that we expect to emerge from this test. + pExpectedNTP := &NTP{ + BaseLayer: BaseLayer{ + Contents: []byte{0x1a, 0x03, 0x0a, 0xee, 0x00, 0x00, + 0x1b, 0xf7, 0x00, 0x00, 0x14, 0xec, 0x51, 0xae, + 0x80, 0xb7, 0xc5, 0x02, 0x03, 0x4c, 0x8d, 0x0e, + 0x66, 0xcb, 0xc5, 0x02, 0x04, 0xec, 0xec, 0x42, + 0xee, 0x92, 0xc5, 0x02, 0x04, 0xeb, 0xcf, 0x49, + 0x59, 0xe6, 0xc5, 0x02, 0x04, 0xeb, 0xcf, 0x4c, + 0x6e, 0x6e}, + Payload: nil, + }, + LeapIndicator: 0, + Version: 3, + Mode: 2, + Stratum: 3, + Poll: 10, + Precision: -18, + RootDelay: 0x1bf7, + RootDispersion: 0x14ec, + ReferenceID: 0x51ae80b7, + ReferenceTimestamp: 0xc502034c8d0e66cb, + OriginTimestamp: 0xc50204ecec42ee92, + ReceiveTimestamp: 0xc50204ebcf4959e6, + TransmitTimestamp: 0xc50204ebcf4c6e6e, + ExtensionBytes: []byte{}, + } + + checkNTP("test02", t, testPacketNTP, pExpectedNTP) +} + +//****************************************************************************** + +func TestNTPThree(t *testing.T) { + + // This test packet is packet #19 in the NTP sample capture + // pcap file NTP_sync.pcap on the Wireshark sample captures page: + // + // https://wiki.wireshark.org/SampleCaptures + // https://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=get&target=NTP_sync.pcap + + var testPacketNTP = []byte{ + 0x00, 0xd0, 0x59, 0x6c, 0x40, 0x4e, 0x00, 0x0c, + 0x41, 0x82, 0xb2, 0x53, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x4c, 0x00, 0x00, 0x40, 0x00, 0x30, 0x11, + 0x74, 0x65, 0x18, 0x7b, 0xca, 0xe6, 0xc0, 0xa8, + 0x32, 0x32, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x38, + 0x44, 0x05, 0x1a, 0x02, 0x0a, 0xec, 0x00, 0x00, + 0x07, 0xc3, 0x00, 0x00, 0x2f, 0x80, 0xc6, 0x1e, + 0x5c, 0x02, 0xc5, 0x01, 0xf9, 0x95, 0x42, 0x50, + 0x82, 0xcf, 0xc5, 0x02, 0x04, 0xec, 0xec, 0x42, + 0xee, 0x92, 0xc5, 0x02, 0x04, 0xeb, 0xd2, 0x35, + 0x2e, 0xb5, 0xc5, 0x02, 0x04, 0xeb, 0xd2, 0x35, + 0xd6, 0x7b, + } + + // Assemble the NTP object that we expect to emerge from this test. + pExpectedNTP := &NTP{ + BaseLayer: BaseLayer{ + Contents: []byte{0x1a, 0x02, 0x0a, 0xec, 0x00, 0x00, + 0x07, 0xc3, 0x00, 0x00, 0x2f, 0x80, 0xc6, 0x1e, + 0x5c, 0x02, 0xc5, 0x01, 0xf9, 0x95, 0x42, 0x50, + 0x82, 0xcf, 0xc5, 0x02, 0x04, 0xec, 0xec, 0x42, + 0xee, 0x92, 0xc5, 0x02, 0x04, 0xeb, 0xd2, 0x35, + 0x2e, 0xb5, 0xc5, 0x02, 0x04, 0xeb, 0xd2, 0x35, + 0xd6, 0x7b}, + Payload: nil, + }, + LeapIndicator: 0, + Version: 3, + Mode: 2, + Stratum: 2, + Poll: 10, + Precision: -20, + RootDelay: 0x7c3, + RootDispersion: 0x2f80, + ReferenceID: 0xc61e5c02, + ReferenceTimestamp: 0xc501f995425082cf, + OriginTimestamp: 0xc50204ecec42ee92, + ReceiveTimestamp: 0xc50204ebd2352eb5, + TransmitTimestamp: 0xc50204ebd235d67b, + ExtensionBytes: []byte{}, + } + + checkNTP("test03", t, testPacketNTP, pExpectedNTP) +} + +//****************************************************************************** + +// TestNTPIsomorphism tests whether random data gets parsed into NTP layer and +// gets serialized back from it to the same value. +func TestNTPIsomorphism(t *testing.T) { + NTPData := make([]byte, ntpMinimumRecordSizeInBytes+7) + _, err := io.ReadFull(rand.Reader, NTPData) + if err != nil { + t.Error(err) + } + ntpLayer := &NTP{} + err = ntpLayer.DecodeFromBytes(NTPData, gopacket.NilDecodeFeedback) + if err != nil { + t.Error(err) + } + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{} + err = ntpLayer.SerializeTo(buf, opts) + if err != nil { + t.Error(err) + } + if !reflect.DeepEqual(NTPData, buf.Bytes()) { + t.Errorf("NTP packet is not isomorphic:\ngot :\n%x\n\nwant :\n%x\n\n", buf.Bytes(), NTPData) + } +} diff --git a/vendor/github.com/google/gopacket/layers/ospf.go b/vendor/github.com/google/gopacket/layers/ospf.go new file mode 100644 index 0000000..eee8542 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/ospf.go @@ -0,0 +1,509 @@ +// Copyright 2017 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "fmt" + + "github.com/google/gopacket" +) + +// OSPFType denotes what kind of OSPF type it is +type OSPFType uint8 + +// Potential values for OSPF.Type. +const ( + OSPFHello OSPFType = 1 + OSPFDatabaseDescription OSPFType = 2 + OSPFLinkStateRequest OSPFType = 3 + OSPFLinkStateUpdate OSPFType = 4 + OSPFLinkStateAcknowledgment OSPFType = 5 +) + +// LSA Function Codes for LSAheader.LSType +const ( + RouterLSAtype = 0x2001 + NetworkLSAtype = 0x2002 + InterAreaPrefixLSAtype = 0x2003 + InterAreaRouterLSAtype = 0x2004 + ASExternalLSAtype = 0x4005 + NSSALSAtype = 0x2007 + LinkLSAtype = 0x0008 + IntraAreaPrefixLSAtype = 0x2009 +) + +// String conversions for OSPFType +func (i OSPFType) String() string { + switch i { + case OSPFHello: + return "Hello" + case OSPFDatabaseDescription: + return "Database Description" + case OSPFLinkStateRequest: + return "Link State Request" + case OSPFLinkStateUpdate: + return "Link State Update" + case OSPFLinkStateAcknowledgment: + return "Link State Acknowledgment" + default: + return "" + } +} + +// Prefix extends IntraAreaPrefixLSA +type Prefix struct { + PrefixLength uint8 + PrefixOptions uint8 + Metric uint16 + AddressPrefix []byte +} + +// IntraAreaPrefixLSA is the struct from RFC 5340 A.4.10. +type IntraAreaPrefixLSA struct { + NumOfPrefixes uint16 + RefLSType uint16 + RefLinkStateID uint32 + RefAdvRouter uint32 + Prefixes []Prefix +} + +// LinkLSA is the struct from RFC 5340 A.4.9. +type LinkLSA struct { + RtrPriority uint8 + Options uint32 + LinkLocalAddress []byte + NumOfPrefixes uint32 + Prefixes []Prefix +} + +// ASExternalLSA is the struct from RFC 5340 A.4.7. +type ASExternalLSA struct { + Flags uint8 + Metric uint32 + PrefixLength uint8 + PrefixOptions uint8 + RefLSType uint16 + AddressPrefix []byte + ForwardingAddress []byte + ExternalRouteTag uint32 + RefLinkStateID uint32 +} + +// InterAreaRouterLSA is the struct from RFC 5340 A.4.6. +type InterAreaRouterLSA struct { + Options uint32 + Metric uint32 + DestinationRouterID uint32 +} + +// InterAreaPrefixLSA is the struct from RFC 5340 A.4.5. +type InterAreaPrefixLSA struct { + Metric uint32 + PrefixLength uint8 + PrefixOptions uint8 + AddressPrefix []byte +} + +// NetworkLSA is the struct from RFC 5340 A.4.4. +type NetworkLSA struct { + Options uint32 + AttachedRouter []uint32 +} + +// Router extends RouterLSA +type Router struct { + Type uint8 + Metric uint16 + InterfaceID uint32 + NeighborInterfaceID uint32 + NeighborRouterID uint32 +} + +// RouterLSA is the struct from RFC 5340 A.4.3. +type RouterLSA struct { + Flags uint8 + Options uint32 + Routers []Router +} + +// LSAheader is the struct from RFC 5340 A.4.2. +type LSAheader struct { + LSAge uint16 + LSType uint16 + LinkStateID uint32 + AdvRouter uint32 + LSSeqNumber uint32 + LSChecksum uint16 + Length uint16 +} + +// LSA links LSAheader with the structs from RFC 5340 A.4. +type LSA struct { + LSAheader + Content interface{} +} + +// LSUpdate is the struct from RFC 5340 A.3.5. +type LSUpdate struct { + NumOfLSAs uint32 + LSAs []LSA +} + +// LSReq is the struct from RFC 5340 A.3.4. +type LSReq struct { + LSType uint16 + LSID uint32 + AdvRouter uint32 +} + +// DbDescPkg is the struct from RFC 5340 A.3.3. +type DbDescPkg struct { + Options uint32 + InterfaceMTU uint16 + Flags uint16 + DDSeqNumber uint32 + LSAinfo []LSAheader +} + +// HelloPkg is the struct from RFC 5340 A.3.2. +type HelloPkg struct { + InterfaceID uint32 + RtrPriority uint8 + Options uint32 + HelloInterval uint16 + RouterDeadInterval uint16 + DesignatedRouterID uint32 + BackupDesignatedRouterID uint32 + NeighborID []uint32 +} + +// HelloPkgV2 extends the HelloPkg struct with OSPFv2 information +type HelloPkgV2 struct { + HelloPkg + NetworkMask uint32 +} + +// OSPF is a basic OSPF packet header with common fields of Version 2 and Version 3. +type OSPF struct { + Version uint8 + Type OSPFType + PacketLength uint16 + RouterID uint32 + AreaID uint32 + Checksum uint16 + Content interface{} +} + +//OSPFv2 extend the OSPF head with version 2 specific fields +type OSPFv2 struct { + BaseLayer + OSPF + AuType uint16 + Authentication uint64 +} + +// OSPFv3 extend the OSPF head with version 3 specific fields +type OSPFv3 struct { + BaseLayer + OSPF + Instance uint8 + Reserved uint8 +} + +// getLSAs parses the LSA information from the packet +func getLSAs(num uint32, data []byte) ([]LSA, error) { + var lsas []LSA + var i uint32 = 0 + var offset uint32 = 0 + for ; i < num; i++ { + var content interface{} + lstype := binary.BigEndian.Uint16(data[offset+2 : offset+4]) + lsalength := binary.BigEndian.Uint16(data[offset+18 : offset+20]) + + switch lstype { + case RouterLSAtype: + var routers []Router + var j uint32 + for j = 24; j < uint32(lsalength); j += 16 { + router := Router{ + Type: uint8(data[offset+j]), + Metric: binary.BigEndian.Uint16(data[offset+j+2 : offset+j+4]), + InterfaceID: binary.BigEndian.Uint32(data[offset+j+4 : offset+j+8]), + NeighborInterfaceID: binary.BigEndian.Uint32(data[offset+j+8 : offset+j+12]), + NeighborRouterID: binary.BigEndian.Uint32(data[offset+j+12 : offset+j+16]), + } + routers = append(routers, router) + } + content = RouterLSA{ + Flags: uint8(data[offset+20]), + Options: binary.BigEndian.Uint32(data[offset+20:offset+24]) & 0x00FFFFFF, + Routers: routers, + } + case NetworkLSAtype: + var routers []uint32 + var j uint32 + for j = 24; j < uint32(lsalength); j += 4 { + routers = append(routers, binary.BigEndian.Uint32(data[offset+j:offset+j+4])) + } + content = NetworkLSA{ + Options: binary.BigEndian.Uint32(data[offset+20:offset+24]) & 0x00FFFFFF, + AttachedRouter: routers, + } + case InterAreaPrefixLSAtype: + content = InterAreaPrefixLSA{ + Metric: binary.BigEndian.Uint32(data[offset+20:offset+24]) & 0x00FFFFFF, + PrefixLength: uint8(data[offset+24]), + PrefixOptions: uint8(data[offset+25]), + AddressPrefix: data[offset+28 : offset+uint32(lsalength)], + } + case InterAreaRouterLSAtype: + content = InterAreaRouterLSA{ + Options: binary.BigEndian.Uint32(data[offset+20:offset+24]) & 0x00FFFFFF, + Metric: binary.BigEndian.Uint32(data[offset+24:offset+28]) & 0x00FFFFFF, + DestinationRouterID: binary.BigEndian.Uint32(data[offset+28 : offset+32]), + } + case ASExternalLSAtype: + fallthrough + case NSSALSAtype: + + flags := uint8(data[offset+20]) + prefixLen := uint8(data[offset+24]) / 8 + var forwardingAddress []byte + if (flags & 0x02) == 0x02 { + forwardingAddress = data[offset+28+uint32(prefixLen) : offset+28+uint32(prefixLen)+16] + } + content = ASExternalLSA{ + Flags: flags, + Metric: binary.BigEndian.Uint32(data[offset+20:offset+24]) & 0x00FFFFFF, + PrefixLength: prefixLen, + PrefixOptions: uint8(data[offset+25]), + RefLSType: binary.BigEndian.Uint16(data[offset+26 : offset+28]), + AddressPrefix: data[offset+28 : offset+28+uint32(prefixLen)], + ForwardingAddress: forwardingAddress, + } + case LinkLSAtype: + var prefixes []Prefix + var prefixOffset uint32 = offset + 44 + var j uint32 + numOfPrefixes := binary.BigEndian.Uint32(data[offset+40 : offset+44]) + for j = 0; j < numOfPrefixes; j++ { + prefixLen := uint8(data[prefixOffset]) + prefix := Prefix{ + PrefixLength: prefixLen, + PrefixOptions: uint8(data[prefixOffset+1]), + AddressPrefix: data[prefixOffset+4 : prefixOffset+4+uint32(prefixLen)/8], + } + prefixes = append(prefixes, prefix) + prefixOffset = prefixOffset + 4 + uint32(prefixLen)/8 + } + content = LinkLSA{ + RtrPriority: uint8(data[offset+20]), + Options: binary.BigEndian.Uint32(data[offset+20:offset+24]) & 0x00FFFFFF, + LinkLocalAddress: data[offset+24 : offset+40], + NumOfPrefixes: numOfPrefixes, + Prefixes: prefixes, + } + case IntraAreaPrefixLSAtype: + var prefixes []Prefix + var prefixOffset uint32 = offset + 32 + var j uint16 + numOfPrefixes := binary.BigEndian.Uint16(data[offset+20 : offset+22]) + for j = 0; j < numOfPrefixes; j++ { + prefixLen := uint8(data[prefixOffset]) + prefix := Prefix{ + PrefixLength: prefixLen, + PrefixOptions: uint8(data[prefixOffset+1]), + Metric: binary.BigEndian.Uint16(data[prefixOffset+2 : prefixOffset+4]), + AddressPrefix: data[prefixOffset+4 : prefixOffset+4+uint32(prefixLen)/8], + } + prefixes = append(prefixes, prefix) + prefixOffset = prefixOffset + 4 + uint32(prefixLen) + } + content = IntraAreaPrefixLSA{ + NumOfPrefixes: numOfPrefixes, + RefLSType: binary.BigEndian.Uint16(data[offset+22 : offset+24]), + RefLinkStateID: binary.BigEndian.Uint32(data[offset+24 : offset+28]), + RefAdvRouter: binary.BigEndian.Uint32(data[offset+28 : offset+32]), + Prefixes: prefixes, + } + default: + return nil, fmt.Errorf("Unknown Link State type.") + } + lsa := LSA{ + LSAheader: LSAheader{ + LSAge: binary.BigEndian.Uint16(data[offset : offset+2]), + LSType: lstype, + LinkStateID: binary.BigEndian.Uint32(data[offset+4 : offset+8]), + AdvRouter: binary.BigEndian.Uint32(data[offset+8 : offset+12]), + LSSeqNumber: binary.BigEndian.Uint32(data[offset+12 : offset+16]), + LSChecksum: binary.BigEndian.Uint16(data[offset+16 : offset+18]), + Length: lsalength, + }, + Content: content, + } + lsas = append(lsas, lsa) + offset += uint32(lsalength) + } + return lsas, nil +} + +// DecodeFromBytes decodes the given bytes into the OSPF layer. +func (ospf *OSPFv2) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 24 { + return fmt.Errorf("Packet too smal for OSPF Version 2") + } + + ospf.Version = uint8(data[0]) + ospf.Type = OSPFType(data[1]) + ospf.PacketLength = binary.BigEndian.Uint16(data[2:4]) + ospf.RouterID = binary.BigEndian.Uint32(data[4:8]) + ospf.AreaID = binary.BigEndian.Uint32(data[8:12]) + ospf.Checksum = binary.BigEndian.Uint16(data[12:14]) + ospf.AuType = binary.BigEndian.Uint16(data[14:16]) + ospf.Authentication = binary.BigEndian.Uint64(data[16:24]) + + return nil +} + +// DecodeFromBytes decodes the given bytes into the OSPF layer. +func (ospf *OSPFv3) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + + if len(data) < 16 { + return fmt.Errorf("Packet too smal for OSPF Version 3") + } + + ospf.Version = uint8(data[0]) + ospf.Type = OSPFType(data[1]) + ospf.PacketLength = binary.BigEndian.Uint16(data[2:4]) + ospf.RouterID = binary.BigEndian.Uint32(data[4:8]) + ospf.AreaID = binary.BigEndian.Uint32(data[8:12]) + ospf.Checksum = binary.BigEndian.Uint16(data[12:14]) + ospf.Instance = uint8(data[14]) + ospf.Reserved = uint8(data[15]) + + switch ospf.Type { + case OSPFHello: + var neighbors []uint32 + for i := 36; uint16(i+4) <= ospf.PacketLength; i += 4 { + neighbors = append(neighbors, binary.BigEndian.Uint32(data[i:i+4])) + } + ospf.Content = HelloPkg{ + InterfaceID: binary.BigEndian.Uint32(data[16:20]), + RtrPriority: uint8(data[20]), + Options: binary.BigEndian.Uint32(data[21:25]) >> 8, + HelloInterval: binary.BigEndian.Uint16(data[24:26]), + RouterDeadInterval: binary.BigEndian.Uint16(data[26:28]), + DesignatedRouterID: binary.BigEndian.Uint32(data[28:32]), + BackupDesignatedRouterID: binary.BigEndian.Uint32(data[32:36]), + NeighborID: neighbors, + } + case OSPFDatabaseDescription: + var lsas []LSAheader + for i := 28; uint16(i+20) <= ospf.PacketLength; i += 20 { + lsa := LSAheader{ + LSAge: binary.BigEndian.Uint16(data[i : i+2]), + LSType: binary.BigEndian.Uint16(data[i+2 : i+4]), + LinkStateID: binary.BigEndian.Uint32(data[i+4 : i+8]), + AdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]), + LSSeqNumber: binary.BigEndian.Uint32(data[i+12 : i+16]), + LSChecksum: binary.BigEndian.Uint16(data[i+16 : i+18]), + Length: binary.BigEndian.Uint16(data[i+18 : i+20]), + } + lsas = append(lsas, lsa) + } + ospf.Content = DbDescPkg{ + Options: binary.BigEndian.Uint32(data[16:20]) & 0x00FFFFFF, + InterfaceMTU: binary.BigEndian.Uint16(data[20:22]), + Flags: binary.BigEndian.Uint16(data[22:24]), + DDSeqNumber: binary.BigEndian.Uint32(data[24:28]), + LSAinfo: lsas, + } + case OSPFLinkStateRequest: + var lsrs []LSReq + for i := 16; uint16(i+12) <= ospf.PacketLength; i += 12 { + lsr := LSReq{ + LSType: binary.BigEndian.Uint16(data[i+2 : i+4]), + LSID: binary.BigEndian.Uint32(data[i+4 : i+8]), + AdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]), + } + lsrs = append(lsrs, lsr) + } + ospf.Content = lsrs + case OSPFLinkStateUpdate: + num := binary.BigEndian.Uint32(data[16:20]) + lsas, err := getLSAs(num, data[20:]) + if err != nil { + return fmt.Errorf("Cannot parse Link State Update packet: %v", err) + } + ospf.Content = LSUpdate{ + NumOfLSAs: num, + LSAs: lsas, + } + + case OSPFLinkStateAcknowledgment: + var lsas []LSAheader + for i := 16; uint16(i+20) <= ospf.PacketLength; i += 20 { + lsa := LSAheader{ + LSAge: binary.BigEndian.Uint16(data[i : i+2]), + LSType: binary.BigEndian.Uint16(data[i+2 : i+4]), + LinkStateID: binary.BigEndian.Uint32(data[i+4 : i+8]), + AdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]), + LSSeqNumber: binary.BigEndian.Uint32(data[i+12 : i+16]), + LSChecksum: binary.BigEndian.Uint16(data[i+16 : i+18]), + Length: binary.BigEndian.Uint16(data[i+18 : i+20]), + } + lsas = append(lsas, lsa) + } + ospf.Content = lsas + default: + } + + return nil +} + +// LayerType returns LayerTypeOSPF +func (ospf *OSPFv2) LayerType() gopacket.LayerType { + return LayerTypeOSPF +} +func (ospf *OSPFv3) LayerType() gopacket.LayerType { + return LayerTypeOSPF +} + +// NextLayerType returns the layer type contained by this DecodingLayer. +func (ospf *OSPFv2) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypeZero +} +func (ospf *OSPFv3) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypeZero +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (ospf *OSPFv2) CanDecode() gopacket.LayerClass { + return LayerTypeOSPF +} +func (ospf *OSPFv3) CanDecode() gopacket.LayerClass { + return LayerTypeOSPF +} + +func decodeOSPF(data []byte, p gopacket.PacketBuilder) error { + if len(data) < 14 { + return fmt.Errorf("Packet too smal for OSPF") + } + + switch uint8(data[0]) { + case 2: + ospf := &OSPFv2{} + return decodingLayerDecoder(ospf, data, p) + case 3: + ospf := &OSPFv3{} + return decodingLayerDecoder(ospf, data, p) + default: + } + + return fmt.Errorf("Unable to determine OSPF type.") +} diff --git a/vendor/github.com/google/gopacket/layers/ospf_test.go b/vendor/github.com/google/gopacket/layers/ospf_test.go new file mode 100644 index 0000000..930bb4d --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/ospf_test.go @@ -0,0 +1,559 @@ +// Copyright 2017 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "github.com/google/gopacket" + "reflect" + "testing" +) + +// testPacketOSPF3Hello is the packet: +// 14:43:11.663317 IP6 fe80::1 > ff02::5: OSPFv3, Hello, length 36 +// 0x0000: 3333 0000 0005 c200 1ffa 0001 86dd 6e00 33............n. +// 0x0010: 0000 0024 5901 fe80 0000 0000 0000 0000 ...$Y........... +// 0x0020: 0000 0000 0001 ff02 0000 0000 0000 0000 ................ +// 0x0030: 0000 0000 0005 0301 0024 0101 0101 0000 .........$...... +// 0x0040: 0001 fb86 0000 0000 0005 0100 0013 000a ................ +// 0x0050: 0028 0000 0000 0000 0000 .(........ +var testPacketOSPF3Hello = []byte{ + 0x33, 0x33, 0x00, 0x00, 0x00, 0x05, 0xc2, 0x00, 0x1f, 0xfa, 0x00, 0x01, 0x86, 0xdd, 0x6e, 0x00, + 0x00, 0x00, 0x00, 0x24, 0x59, 0x01, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x03, 0x01, 0x00, 0x24, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, + 0x00, 0x01, 0xfb, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x01, 0x00, 0x00, 0x13, 0x00, 0x0a, + 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +} + +func TestPacketOSPF3Hello(t *testing.T) { + p := gopacket.NewPacket(testPacketOSPF3Hello, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv6, LayerTypeOSPF}, t) + + ospf := p.Layer(LayerTypeOSPF).(*OSPFv3) + if ospf.Version != 3 { + t.Fatal("Invalid OSPF version") + } + if got, ok := p.Layer(LayerTypeOSPF).(*OSPFv3); ok { + want := &OSPFv3{ + OSPF: OSPF{ + Version: 3, + Type: OSPFHello, + PacketLength: 36, + RouterID: 0x1010101, + AreaID: 1, + Checksum: 0xfb86, + Content: HelloPkg{ + InterfaceID: 5, + RtrPriority: 1, + Options: 0x000013, + HelloInterval: 10, + RouterDeadInterval: 40, + DesignatedRouterID: 0, + BackupDesignatedRouterID: 0, + }, + }, + Instance: 0, + Reserved: 0, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("OSPF packet processing failed:\ngot :\n%#v\n\nwant :\n%#v\n\n", got, want) + } + } else { + t.Error("No OSPF layer type found in packet") + } +} +func BenchmarkDecodePacketPacket0(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketOSPF3Hello, LinkTypeEthernet, gopacket.NoCopy) + } +} + +// testPacketOSPF3DBDesc is the packet: +// 14:43:51.657571 IP6 fe80::2 > fe80::1: OSPFv3, Database Description, length 28 +// 0x0000: c200 1ffa 0001 c201 1ffa 0001 86dd 6e00 ..............n. +// 0x0010: 0000 001c 5901 fe80 0000 0000 0000 0000 ....Y........... +// 0x0020: 0000 0000 0002 fe80 0000 0000 0000 0000 ................ +// 0x0030: 0000 0000 0001 0302 001c 0202 0202 0000 ................ +// 0x0040: 0001 d826 0000 0000 0013 05dc 0007 0000 ...&............ +// 0x0050: 1d46 .F +var testPacketOSPF3DBDesc = []byte{ + 0xc2, 0x00, 0x1f, 0xfa, 0x00, 0x01, 0xc2, 0x01, 0x1f, 0xfa, 0x00, 0x01, 0x86, 0xdd, 0x6e, 0x00, + 0x00, 0x00, 0x00, 0x1c, 0x59, 0x01, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x02, 0x00, 0x1c, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, + 0x00, 0x01, 0xd8, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x05, 0xdc, 0x00, 0x07, 0x00, 0x00, + 0x1d, 0x46, +} + +func TestPacketOSPF3DBDesc(t *testing.T) { + p := gopacket.NewPacket(testPacketOSPF3DBDesc, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv6, LayerTypeOSPF}, t) + if got, ok := p.Layer(LayerTypeOSPF).(*OSPFv3); ok { + want := &OSPFv3{ + OSPF: OSPF{ + Version: 3, + Type: OSPFDatabaseDescription, + PacketLength: 28, + RouterID: 0x2020202, + AreaID: 1, + Checksum: 0xd826, + Content: DbDescPkg{ + Options: 0x000013, + InterfaceMTU: 1500, + Flags: 0x7, + DDSeqNumber: 7494, + }, + }, + Instance: 0, + Reserved: 0, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("OSPF packet processing failed:\ngot :\n%#v\n\nwant :\n%#v\n\n", got, want) + } + } else { + t.Error("No OSPF layer type found in packet") + } +} +func BenchmarkDecodePacketPacket1(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketOSPF3DBDesc, LinkTypeEthernet, gopacket.NoCopy) + } +} + +// testPacketOSPF3LSRequest is the packet: +// 14:43:51.673584 IP6 fe80::2 > fe80::1: OSPFv3, LS-Request, length 100 +// 0x0000: c200 1ffa 0001 c201 1ffa 0001 86dd 6e00 ..............n. +// 0x0010: 0000 0064 5901 fe80 0000 0000 0000 0000 ...dY........... +// 0x0020: 0000 0000 0002 fe80 0000 0000 0000 0000 ................ +// 0x0030: 0000 0000 0001 0303 0064 0202 0202 0000 .........d...... +// 0x0040: 0001 2c9a 0000 0000 2001 0000 0000 0101 ..,............. +// 0x0050: 0101 0000 2003 0000 0003 0101 0101 0000 ................ +// 0x0060: 2003 0000 0002 0101 0101 0000 2003 0000 ................ +// 0x0070: 0001 0101 0101 0000 2003 0000 0000 0101 ................ +// 0x0080: 0101 0000 0008 0000 0005 0101 0101 0000 ................ +// 0x0090: 2009 0000 0000 0101 0101 .......... +var testPacketOSPF3LSRequest = []byte{ + 0xc2, 0x00, 0x1f, 0xfa, 0x00, 0x01, 0xc2, 0x01, 0x1f, 0xfa, 0x00, 0x01, 0x86, 0xdd, 0x6e, 0x00, + 0x00, 0x00, 0x00, 0x64, 0x59, 0x01, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x00, 0x64, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, + 0x00, 0x01, 0x2c, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, + 0x01, 0x01, 0x00, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, + 0x20, 0x03, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x20, 0x03, 0x00, 0x00, + 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, + 0x01, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x05, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, + 0x20, 0x09, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, +} + +func TestPacketOSPF3LSRequest(t *testing.T) { + p := gopacket.NewPacket(testPacketOSPF3LSRequest, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv6, LayerTypeOSPF}, t) + if got, ok := p.Layer(LayerTypeOSPF).(*OSPFv3); ok { + want := &OSPFv3{ + OSPF: OSPF{ + Version: 3, + Type: OSPFLinkStateRequest, + PacketLength: 100, + RouterID: 0x2020202, + AreaID: 1, + Checksum: 0x2c9a, + Content: []LSReq{ + LSReq{ + LSType: 0x2001, + LSID: 0x00000000, + AdvRouter: 0x01010101, + }, + LSReq{ + LSType: 0x2003, + LSID: 0x00000003, + AdvRouter: 0x01010101, + }, + LSReq{ + LSType: 0x2003, + LSID: 0x00000002, + AdvRouter: 0x01010101, + }, + LSReq{ + LSType: 0x2003, + LSID: 0x00000001, + AdvRouter: 0x01010101, + }, + LSReq{ + LSType: 0x2003, + LSID: 0x00000000, + AdvRouter: 0x01010101, + }, + LSReq{ + LSType: 0x0008, + LSID: 0x00000005, + AdvRouter: 0x01010101, + }, + LSReq{ + LSType: 0x2009, + LSID: 0x00000000, + AdvRouter: 0x01010101, + }, + }, + }, + Instance: 0, + Reserved: 0, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("OSPF packet processing failed:\ngot :\n%#v\n\nwant :\n%#v\n\n", got, want) + } + } else { + t.Error("No OSPF layer type found in packet") + } +} +func BenchmarkDecodePacketPacket2(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketOSPF3LSRequest, LinkTypeEthernet, gopacket.NoCopy) + } +} + +// testPacketOSPF3LSUpdate is the packet: +// 14:43:51.681554 IP6 fe80::1 > fe80::2: OSPFv3, LS-Update, length 288 +// 0x0000: c201 1ffa 0001 c200 1ffa 0001 86dd 6e00 ..............n. +// 0x0010: 0000 0120 5901 fe80 0000 0000 0000 0000 ....Y........... +// 0x0020: 0000 0000 0001 fe80 0000 0000 0000 0000 ................ +// 0x0030: 0000 0000 0002 0304 0120 0101 0101 0000 ................ +// 0x0040: 0001 e556 0000 0000 0007 0028 2001 0000 ...V.......(.... +// 0x0050: 0000 0101 0101 8000 0002 d13a 0018 0100 ...........:.... +// 0x0060: 0033 0029 2003 0000 0003 0101 0101 8000 .3.)............ +// 0x0070: 0001 6259 0024 0000 004a 4000 0000 2001 ..bY.$...J@..... +// 0x0080: 0db8 0000 0003 0029 2003 0000 0002 0101 .......)........ +// 0x0090: 0101 8000 0001 baf6 0024 0000 0054 4000 .........$...T@. +// 0x00a0: 0000 2001 0db8 0000 0004 0029 2003 0000 ...........).... +// 0x00b0: 0001 0101 0101 8000 0001 eba0 0024 0000 .............$.. +// 0x00c0: 004a 4000 0000 2001 0db8 0000 0034 0029 .J@..........4.) +// 0x00d0: 2003 0000 0000 0101 0101 8000 0001 0ebd ................ +// 0x00e0: 0024 0000 0040 4000 0000 2001 0db8 0000 .$...@@......... +// 0x00f0: 0000 0023 0008 0000 0005 0101 0101 8000 ...#............ +// 0x0100: 0002 3d08 0038 0100 0033 fe80 0000 0000 ..=..8...3...... +// 0x0110: 0000 0000 0000 0000 0001 0000 0001 4000 ..............@. +// 0x0120: 0000 2001 0db8 0000 0012 0023 2009 0000 ...........#.... +// 0x0130: 0000 0101 0101 8000 0001 e8d2 002c 0001 .............,.. +// 0x0140: 2001 0000 0000 0101 0101 4000 000a 2001 ..........@..... +// 0x0150: 0db8 0000 0012 ...... +var testPacketOSPF3LSUpdate = []byte{ + 0xc2, 0x01, 0x1f, 0xfa, 0x00, 0x01, 0xc2, 0x00, 0x1f, 0xfa, 0x00, 0x01, 0x86, 0xdd, 0x6e, 0x00, + 0x00, 0x00, 0x01, 0x20, 0x59, 0x01, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x04, 0x01, 0x20, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, + 0x00, 0x01, 0xe5, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x28, 0x20, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x80, 0x00, 0x00, 0x02, 0xd1, 0x3a, 0x00, 0x18, 0x01, 0x00, + 0x00, 0x33, 0x00, 0x29, 0x20, 0x03, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x80, 0x00, + 0x00, 0x01, 0x62, 0x59, 0x00, 0x24, 0x00, 0x00, 0x00, 0x4a, 0x40, 0x00, 0x00, 0x00, 0x20, 0x01, + 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x03, 0x00, 0x29, 0x20, 0x03, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, + 0x01, 0x01, 0x80, 0x00, 0x00, 0x01, 0xba, 0xf6, 0x00, 0x24, 0x00, 0x00, 0x00, 0x54, 0x40, 0x00, + 0x00, 0x00, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x04, 0x00, 0x29, 0x20, 0x03, 0x00, 0x00, + 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x00, 0x00, 0x01, 0xeb, 0xa0, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x4a, 0x40, 0x00, 0x00, 0x00, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x34, 0x00, 0x29, + 0x20, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x80, 0x00, 0x00, 0x01, 0x0e, 0xbd, + 0x00, 0x24, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x23, 0x00, 0x08, 0x00, 0x00, 0x00, 0x05, 0x01, 0x01, 0x01, 0x01, 0x80, 0x00, + 0x00, 0x02, 0x3d, 0x08, 0x00, 0x38, 0x01, 0x00, 0x00, 0x33, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, + 0x00, 0x00, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x12, 0x00, 0x23, 0x20, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x80, 0x00, 0x00, 0x01, 0xe8, 0xd2, 0x00, 0x2c, 0x00, 0x01, + 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x40, 0x00, 0x00, 0x0a, 0x20, 0x01, + 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x12, +} + +func TestPacketOSPF3LSUpdate(t *testing.T) { + p := gopacket.NewPacket(testPacketOSPF3LSUpdate, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv6, LayerTypeOSPF}, t) + if got, ok := p.Layer(LayerTypeOSPF).(*OSPFv3); ok { + want := &OSPFv3{ + OSPF: OSPF{ + Version: 3, + Type: OSPFLinkStateUpdate, + PacketLength: 288, + RouterID: 0x1010101, + AreaID: 1, + Checksum: 0xe556, + Content: LSUpdate{ + NumOfLSAs: 7, + LSAs: []LSA{ + LSA{ + LSAheader: LSAheader{ + LSAge: 40, + LSType: 0x2001, + LinkStateID: 0x00000000, + AdvRouter: 0x01010101, + LSSeqNumber: 0x80000002, + LSChecksum: 0xd13a, + Length: 24, + }, + Content: RouterLSA{ + Flags: 0x1, + Options: 0x33, + }, + }, + LSA{ + LSAheader: LSAheader{ + LSAge: 41, + LSType: 0x2003, + LinkStateID: 0x00000003, + AdvRouter: 0x01010101, + LSSeqNumber: 0x80000001, + LSChecksum: 0x6259, + Length: 36, + }, + Content: InterAreaPrefixLSA{ + Metric: 74, + PrefixLength: 64, + PrefixOptions: 0, + AddressPrefix: []byte{0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x03}, + }, + }, + LSA{ + LSAheader: LSAheader{ + LSAge: 41, + LSType: 0x2003, + LinkStateID: 0x00000002, + AdvRouter: 0x01010101, + LSSeqNumber: 0x80000001, + LSChecksum: 0xbaf6, + Length: 36, + }, + Content: InterAreaPrefixLSA{ + Metric: 84, + PrefixLength: 64, + PrefixOptions: 0, + AddressPrefix: []byte{0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x4}, + }, + }, + LSA{ + LSAheader: LSAheader{ + LSAge: 41, + LSType: 0x2003, + LinkStateID: 0x00000001, + AdvRouter: 0x01010101, + LSSeqNumber: 0x80000001, + LSChecksum: 0xeba0, + Length: 36, + }, + Content: InterAreaPrefixLSA{ + Metric: 74, + PrefixLength: 64, + PrefixOptions: 0, + AddressPrefix: []byte{0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x34}, + }, + }, + LSA{ + LSAheader: LSAheader{ + LSAge: 41, + LSType: 0x2003, + LinkStateID: 0x00000000, + AdvRouter: 0x01010101, + LSSeqNumber: 0x80000001, + LSChecksum: 0xebd, + Length: 36, + }, + Content: InterAreaPrefixLSA{ + Metric: 64, + PrefixLength: 64, + PrefixOptions: 0, + AddressPrefix: []byte{0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0}, + }, + }, + LSA{ + LSAheader: LSAheader{ + LSAge: 35, + LSType: 0x8, + LinkStateID: 0x00000005, + AdvRouter: 0x01010101, + LSSeqNumber: 0x80000002, + LSChecksum: 0x3d08, + Length: 56, + }, + Content: LinkLSA{ + RtrPriority: 1, + Options: 0x33, + LinkLocalAddress: []byte{0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + NumOfPrefixes: 1, + Prefixes: []Prefix{ + Prefix{ + PrefixLength: 64, + PrefixOptions: 0, + AddressPrefix: []byte{0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x12}, + }, + }, + }, + }, + LSA{ + LSAheader: LSAheader{ + LSAge: 35, + LSType: 0x2009, + LinkStateID: 0x00000000, + AdvRouter: 0x01010101, + LSSeqNumber: 0x80000001, + LSChecksum: 0xe8d2, + Length: 44, + }, + Content: IntraAreaPrefixLSA{ + NumOfPrefixes: 1, + RefLSType: 0x2001, + RefAdvRouter: 0x01010101, + Prefixes: []Prefix{ + Prefix{ + PrefixLength: 64, + PrefixOptions: 0, + Metric: 10, + AddressPrefix: []byte{0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x12}, + }, + }, + }, + }, + }, + }, + }, + Instance: 0, + Reserved: 0, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("OSPF packet processing failed:\ngot :\n%#v\n\nwant :\n%#v\n\n", got, want) + } + } else { + t.Error("No OSPF layer type found in packet") + } +} +func BenchmarkDecodePacketPacket3(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketOSPF3LSUpdate, LinkTypeEthernet, gopacket.NoCopy) + } +} + +// testPacketOSPF3LSAck is the packet: +// 14:43:54.185384 IP6 fe80::1 > ff02::5: OSPFv3, LS-Ack, length 136 +// 0x0000: 3333 0000 0005 c200 1ffa 0001 86dd 6e00 33............n. +// 0x0010: 0000 0088 5901 fe80 0000 0000 0000 0000 ....Y........... +// 0x0020: 0000 0000 0001 ff02 0000 0000 0000 0000 ................ +// 0x0030: 0000 0000 0005 0305 0088 0101 0101 0000 ................ +// 0x0040: 0001 9d2c 0000 0005 2001 0000 0000 0202 ...,............ +// 0x0050: 0202 8000 0002 b354 0018 0006 2003 0000 .......T........ +// 0x0060: 0003 0202 0202 8000 0001 4473 0024 0006 ..........Ds.$.. +// 0x0070: 2003 0000 0002 0202 0202 8000 0001 9c11 ................ +// 0x0080: 0024 0006 2003 0000 0001 0202 0202 8000 .$.............. +// 0x0090: 0001 cdba 0024 0006 2003 0000 0000 0202 .....$.......... +// 0x00a0: 0202 8000 0001 efd7 0024 0005 0008 0000 .........$...... +// 0x00b0: 0005 0202 0202 8000 0001 5433 002c ..........T3., +var testPacketOSPF3LSAck = []byte{ + 0x33, 0x33, 0x00, 0x00, 0x00, 0x05, 0xc2, 0x00, 0x1f, 0xfa, 0x00, 0x01, 0x86, 0xdd, 0x6e, 0x00, + 0x00, 0x00, 0x00, 0x88, 0x59, 0x01, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x03, 0x05, 0x00, 0x88, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x9d, 0x2c, 0x00, 0x00, 0x00, 0x05, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, + 0x02, 0x02, 0x80, 0x00, 0x00, 0x02, 0xb3, 0x54, 0x00, 0x18, 0x00, 0x06, 0x20, 0x03, 0x00, 0x00, + 0x00, 0x03, 0x02, 0x02, 0x02, 0x02, 0x80, 0x00, 0x00, 0x01, 0x44, 0x73, 0x00, 0x24, 0x00, 0x06, + 0x20, 0x03, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x80, 0x00, 0x00, 0x01, 0x9c, 0x11, + 0x00, 0x24, 0x00, 0x06, 0x20, 0x03, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x80, 0x00, + 0x00, 0x01, 0xcd, 0xba, 0x00, 0x24, 0x00, 0x06, 0x20, 0x03, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, + 0x02, 0x02, 0x80, 0x00, 0x00, 0x01, 0xef, 0xd7, 0x00, 0x24, 0x00, 0x05, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x05, 0x02, 0x02, 0x02, 0x02, 0x80, 0x00, 0x00, 0x01, 0x54, 0x33, 0x00, 0x2c, +} + +func TestPacketOSPF3LSAck(t *testing.T) { + p := gopacket.NewPacket(testPacketOSPF3LSAck, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv6, LayerTypeOSPF}, t) + if got, ok := p.Layer(LayerTypeOSPF).(*OSPFv3); ok { + want := &OSPFv3{ + OSPF: OSPF{ + Version: 3, + Type: OSPFLinkStateAcknowledgment, + PacketLength: 136, + RouterID: 0x1010101, + AreaID: 1, + Checksum: 0x9d2c, + Content: []LSAheader{ + LSAheader{ + LSAge: 5, + LSType: 0x2001, + LinkStateID: 0x00000000, + AdvRouter: 0x02020202, + LSSeqNumber: 0x80000002, + LSChecksum: 0xb354, + Length: 24, + }, + LSAheader{ + LSAge: 6, + LSType: 0x2003, + LinkStateID: 0x00000003, + AdvRouter: 0x02020202, + LSSeqNumber: 0x80000001, + LSChecksum: 0x4473, + Length: 36, + }, + LSAheader{ + LSAge: 6, + LSType: 0x2003, + LinkStateID: 0x00000002, + AdvRouter: 0x02020202, + LSSeqNumber: 0x80000001, + LSChecksum: 0x9c11, + Length: 36, + }, + LSAheader{ + LSAge: 6, + LSType: 0x2003, + LinkStateID: 0x00000001, + AdvRouter: 0x02020202, + LSSeqNumber: 0x80000001, + LSChecksum: 0xcdba, + Length: 36, + }, + LSAheader{ + LSAge: 6, + LSType: 0x2003, + LinkStateID: 0x00000000, + AdvRouter: 0x02020202, + LSSeqNumber: 0x80000001, + LSChecksum: 0xefd7, + Length: 36, + }, + LSAheader{ + LSAge: 5, + LSType: 0x0008, + LinkStateID: 0x00000005, + AdvRouter: 0x02020202, + LSSeqNumber: 0x80000001, + LSChecksum: 0x5433, + Length: 44, + }, + }, + }, + Instance: 0, + Reserved: 0, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("OSPF packet processing failed:\ngot :\n%#v\n\nwant :\n%#v\n\n", got, want) + } + } else { + t.Error("No OSPF layer type found in packet") + } +} +func BenchmarkDecodePacketPacket4(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketOSPF3LSAck, LinkTypeEthernet, gopacket.NoCopy) + } +} diff --git a/vendor/github.com/google/gopacket/layers/pflog.go b/vendor/github.com/google/gopacket/layers/pflog.go new file mode 100644 index 0000000..853882f --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/pflog.go @@ -0,0 +1,76 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "errors" + + "github.com/google/gopacket" +) + +type PFDirection uint8 + +const ( + PFDirectionInOut PFDirection = 0 + PFDirectionIn PFDirection = 1 + PFDirectionOut PFDirection = 2 +) + +// PFLog provides the layer for 'pf' packet-filter logging, as described at +// http://www.freebsd.org/cgi/man.cgi?query=pflog&sektion=4 +type PFLog struct { + BaseLayer + Length uint8 + Family ProtocolFamily + Action, Reason uint8 + IFName, Ruleset []byte + RuleNum, SubruleNum uint32 + UID uint32 + PID int32 + RuleUID uint32 + RulePID int32 + Direction PFDirection + // The remainder is padding +} + +func (pf *PFLog) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + pf.Length = data[0] + pf.Family = ProtocolFamily(data[1]) + pf.Action = data[2] + pf.Reason = data[3] + pf.IFName = data[4:20] + pf.Ruleset = data[20:36] + pf.RuleNum = binary.BigEndian.Uint32(data[36:40]) + pf.SubruleNum = binary.BigEndian.Uint32(data[40:44]) + pf.UID = binary.BigEndian.Uint32(data[44:48]) + pf.PID = int32(binary.BigEndian.Uint32(data[48:52])) + pf.RuleUID = binary.BigEndian.Uint32(data[52:56]) + pf.RulePID = int32(binary.BigEndian.Uint32(data[56:60])) + pf.Direction = PFDirection(data[60]) + if pf.Length%4 != 1 { + return errors.New("PFLog header length should be 3 less than multiple of 4") + } + actualLength := int(pf.Length) + 3 + pf.Contents = data[:actualLength] + pf.Payload = data[actualLength:] + return nil +} + +// LayerType returns layers.LayerTypePFLog +func (pf *PFLog) LayerType() gopacket.LayerType { return LayerTypePFLog } + +func (pf *PFLog) CanDecode() gopacket.LayerClass { return LayerTypePFLog } + +func (pf *PFLog) NextLayerType() gopacket.LayerType { + return pf.Family.LayerType() +} + +func decodePFLog(data []byte, p gopacket.PacketBuilder) error { + pf := &PFLog{} + return decodingLayerDecoder(pf, data, p) +} diff --git a/vendor/github.com/google/gopacket/layers/ports.go b/vendor/github.com/google/gopacket/layers/ports.go new file mode 100644 index 0000000..431358c --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/ports.go @@ -0,0 +1,140 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "fmt" + "strconv" + + "github.com/google/gopacket" +) + +// TCPPort is a port in a TCP layer. +type TCPPort uint16 + +// UDPPort is a port in a UDP layer. +type UDPPort uint16 + +// RUDPPort is a port in a RUDP layer. +type RUDPPort uint8 + +// SCTPPort is a port in a SCTP layer. +type SCTPPort uint16 + +// UDPLitePort is a port in a UDPLite layer. +type UDPLitePort uint16 + +// RUDPPortNames contains the string names for all RUDP ports. +var RUDPPortNames = map[RUDPPort]string{} + +// UDPLitePortNames contains the string names for all UDPLite ports. +var UDPLitePortNames = map[UDPLitePort]string{} + +// {TCP,UDP,SCTP}PortNames can be found in iana_ports.go + +// String returns the port as "number(name)" if there's a well-known port name, +// or just "number" if there isn't. Well-known names are stored in +// TCPPortNames. +func (a TCPPort) String() string { + if name, ok := TCPPortNames[a]; ok { + return fmt.Sprintf("%d(%s)", a, name) + } + return strconv.Itoa(int(a)) +} + +// LayerType returns a LayerType that would be able to decode the +// application payload. It uses some well-known ports such as 53 for +// DNS. +// +// Returns gopacket.LayerTypePayload for unknown/unsupported port numbers. +func (a TCPPort) LayerType() gopacket.LayerType { + lt := tcpPortLayerType[uint16(a)] + if lt != 0 { + return lt + } + return gopacket.LayerTypePayload +} + +var tcpPortLayerType = [65536]gopacket.LayerType{ + 53: LayerTypeDNS, +} + +// RegisterTCPPortLayerType creates a new mapping between a TCPPort +// and an underlaying LayerType. +func RegisterTCPPortLayerType(port TCPPort, layerType gopacket.LayerType) { + tcpPortLayerType[port] = layerType +} + +// String returns the port as "number(name)" if there's a well-known port name, +// or just "number" if there isn't. Well-known names are stored in +// UDPPortNames. +func (a UDPPort) String() string { + if name, ok := UDPPortNames[a]; ok { + return fmt.Sprintf("%d(%s)", a, name) + } + return strconv.Itoa(int(a)) +} + +// LayerType returns a LayerType that would be able to decode the +// application payload. It uses some well-known ports such as 53 for +// DNS. +// +// Returns gopacket.LayerTypePayload for unknown/unsupported port numbers. +func (a UDPPort) LayerType() gopacket.LayerType { + lt := udpPortLayerType[uint16(a)] + if lt != 0 { + return lt + } + return gopacket.LayerTypePayload +} + +var udpPortLayerType = [65536]gopacket.LayerType{ + 53: LayerTypeDNS, + 123: LayerTypeNTP, + 4789: LayerTypeVXLAN, + 67: LayerTypeDHCPv4, + 68: LayerTypeDHCPv4, + 6343: LayerTypeSFlow, + 6081: LayerTypeGeneve, + 3784: LayerTypeBFD, +} + +// RegisterUDPPortLayerType creates a new mapping between a UDPPort +// and an underlaying LayerType. +func RegisterUDPPortLayerType(port UDPPort, layerType gopacket.LayerType) { + udpPortLayerType[port] = layerType +} + +// String returns the port as "number(name)" if there's a well-known port name, +// or just "number" if there isn't. Well-known names are stored in +// RUDPPortNames. +func (a RUDPPort) String() string { + if name, ok := RUDPPortNames[a]; ok { + return fmt.Sprintf("%d(%s)", a, name) + } + return strconv.Itoa(int(a)) +} + +// String returns the port as "number(name)" if there's a well-known port name, +// or just "number" if there isn't. Well-known names are stored in +// SCTPPortNames. +func (a SCTPPort) String() string { + if name, ok := SCTPPortNames[a]; ok { + return fmt.Sprintf("%d(%s)", a, name) + } + return strconv.Itoa(int(a)) +} + +// String returns the port as "number(name)" if there's a well-known port name, +// or just "number" if there isn't. Well-known names are stored in +// UDPLitePortNames. +func (a UDPLitePort) String() string { + if name, ok := UDPLitePortNames[a]; ok { + return fmt.Sprintf("%d(%s)", a, name) + } + return strconv.Itoa(int(a)) +} diff --git a/vendor/github.com/google/gopacket/layers/ppp.go b/vendor/github.com/google/gopacket/layers/ppp.go new file mode 100644 index 0000000..1d2e7b8 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/ppp.go @@ -0,0 +1,74 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "errors" + "github.com/google/gopacket" +) + +// PPP is the layer for PPP encapsulation headers. +type PPP struct { + BaseLayer + PPPType PPPType +} + +// PPPEndpoint is a singleton endpoint for PPP. Since there is no actual +// addressing for the two ends of a PPP connection, we use a singleton value +// named 'point' for each endpoint. +var PPPEndpoint = gopacket.NewEndpoint(EndpointPPP, nil) + +// PPPFlow is a singleton flow for PPP. Since there is no actual addressing for +// the two ends of a PPP connection, we use a singleton value to represent the +// flow for all PPP connections. +var PPPFlow = gopacket.NewFlow(EndpointPPP, nil, nil) + +// LayerType returns LayerTypePPP +func (p *PPP) LayerType() gopacket.LayerType { return LayerTypePPP } + +// LinkFlow returns PPPFlow. +func (p *PPP) LinkFlow() gopacket.Flow { return PPPFlow } + +func decodePPP(data []byte, p gopacket.PacketBuilder) error { + ppp := &PPP{} + if data[0]&0x1 == 0 { + if data[1]&0x1 == 0 { + return errors.New("PPP has invalid type") + } + ppp.PPPType = PPPType(binary.BigEndian.Uint16(data[:2])) + ppp.Contents = data[:2] + ppp.Payload = data[2:] + } else { + ppp.PPPType = PPPType(data[0]) + ppp.Contents = data[:1] + ppp.Payload = data[1:] + } + p.AddLayer(ppp) + p.SetLinkLayer(ppp) + return p.NextDecoder(ppp.PPPType) +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (p *PPP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + if p.PPPType&0x100 == 0 { + bytes, err := b.PrependBytes(2) + if err != nil { + return err + } + binary.BigEndian.PutUint16(bytes, uint16(p.PPPType)) + } else { + bytes, err := b.PrependBytes(1) + if err != nil { + return err + } + bytes[0] = uint8(p.PPPType) + } + return nil +} diff --git a/vendor/github.com/google/gopacket/layers/pppoe.go b/vendor/github.com/google/gopacket/layers/pppoe.go new file mode 100644 index 0000000..14cd63a --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/pppoe.go @@ -0,0 +1,60 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "github.com/google/gopacket" +) + +// PPPoE is the layer for PPPoE encapsulation headers. +type PPPoE struct { + BaseLayer + Version uint8 + Type uint8 + Code PPPoECode + SessionId uint16 + Length uint16 +} + +// LayerType returns gopacket.LayerTypePPPoE. +func (p *PPPoE) LayerType() gopacket.LayerType { + return LayerTypePPPoE +} + +// 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) +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (p *PPPoE) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + payload := b.Bytes() + bytes, err := b.PrependBytes(6) + if err != nil { + return err + } + bytes[0] = (p.Version << 4) | p.Type + bytes[1] = byte(p.Code) + binary.BigEndian.PutUint16(bytes[2:], p.SessionId) + if opts.FixLengths { + p.Length = uint16(len(payload)) + } + binary.BigEndian.PutUint16(bytes[4:], p.Length) + return nil +} diff --git a/vendor/github.com/google/gopacket/layers/prism.go b/vendor/github.com/google/gopacket/layers/prism.go new file mode 100644 index 0000000..e1711e7 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/prism.go @@ -0,0 +1,146 @@ +// Copyright 2015 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +// http://www.tcpdump.org/linktypes/LINKTYPE_IEEE802_11_PRISM.html + +package layers + +import ( + "encoding/binary" + "errors" + + "github.com/google/gopacket" +) + +func decodePrismValue(data []byte, pv *PrismValue) { + pv.DID = PrismDID(binary.LittleEndian.Uint32(data[0:4])) + pv.Status = binary.LittleEndian.Uint16(data[4:6]) + pv.Length = binary.LittleEndian.Uint16(data[6:8]) + pv.Data = data[8 : 8+pv.Length] +} + +type PrismDID uint32 + +const ( + PrismDIDType1HostTime PrismDID = 0x10044 + PrismDIDType2HostTime PrismDID = 0x01041 + PrismDIDType1MACTime PrismDID = 0x20044 + PrismDIDType2MACTime PrismDID = 0x02041 + PrismDIDType1Channel PrismDID = 0x30044 + PrismDIDType2Channel PrismDID = 0x03041 + PrismDIDType1RSSI PrismDID = 0x40044 + PrismDIDType2RSSI PrismDID = 0x04041 + PrismDIDType1SignalQuality PrismDID = 0x50044 + PrismDIDType2SignalQuality PrismDID = 0x05041 + PrismDIDType1Signal PrismDID = 0x60044 + PrismDIDType2Signal PrismDID = 0x06041 + PrismDIDType1Noise PrismDID = 0x70044 + PrismDIDType2Noise PrismDID = 0x07041 + PrismDIDType1Rate PrismDID = 0x80044 + PrismDIDType2Rate PrismDID = 0x08041 + PrismDIDType1TransmittedFrameIndicator PrismDID = 0x90044 + PrismDIDType2TransmittedFrameIndicator PrismDID = 0x09041 + PrismDIDType1FrameLength PrismDID = 0xA0044 + PrismDIDType2FrameLength PrismDID = 0x0A041 +) + +const ( + PrismType1MessageCode uint16 = 0x00000044 + PrismType2MessageCode uint16 = 0x00000041 +) + +func (p PrismDID) String() string { + dids := map[PrismDID]string{ + PrismDIDType1HostTime: "Host Time", + PrismDIDType2HostTime: "Host Time", + PrismDIDType1MACTime: "MAC Time", + PrismDIDType2MACTime: "MAC Time", + PrismDIDType1Channel: "Channel", + PrismDIDType2Channel: "Channel", + PrismDIDType1RSSI: "RSSI", + PrismDIDType2RSSI: "RSSI", + PrismDIDType1SignalQuality: "Signal Quality", + PrismDIDType2SignalQuality: "Signal Quality", + PrismDIDType1Signal: "Signal", + PrismDIDType2Signal: "Signal", + PrismDIDType1Noise: "Noise", + PrismDIDType2Noise: "Noise", + PrismDIDType1Rate: "Rate", + PrismDIDType2Rate: "Rate", + PrismDIDType1TransmittedFrameIndicator: "Transmitted Frame Indicator", + PrismDIDType2TransmittedFrameIndicator: "Transmitted Frame Indicator", + PrismDIDType1FrameLength: "Frame Length", + PrismDIDType2FrameLength: "Frame Length", + } + + if str, ok := dids[p]; ok { + return str + } + + return "Unknown DID" +} + +type PrismValue struct { + DID PrismDID + Status uint16 + Length uint16 + Data []byte +} + +func (pv *PrismValue) IsSupplied() bool { + return pv.Status == 1 +} + +var ErrPrismExpectedMoreData = errors.New("Expected more data.") +var ErrPrismInvalidCode = errors.New("Invalid header code.") + +func decodePrismHeader(data []byte, p gopacket.PacketBuilder) error { + d := &PrismHeader{} + return decodingLayerDecoder(d, data, p) +} + +type PrismHeader struct { + BaseLayer + Code uint16 + Length uint16 + DeviceName string + Values []PrismValue +} + +func (m *PrismHeader) LayerType() gopacket.LayerType { return LayerTypePrismHeader } + +func (m *PrismHeader) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + m.Code = binary.LittleEndian.Uint16(data[0:4]) + m.Length = binary.LittleEndian.Uint16(data[4:8]) + m.DeviceName = string(data[8:24]) + m.BaseLayer = BaseLayer{Contents: data[:m.Length], Payload: data[m.Length:len(data)]} + + switch m.Code { + case PrismType1MessageCode: + fallthrough + case PrismType2MessageCode: + // valid message code + default: + return ErrPrismInvalidCode + } + + offset := uint16(24) + + m.Values = make([]PrismValue, (m.Length-offset)/12) + for i := 0; i < len(m.Values); i++ { + decodePrismValue(data[offset:offset+12], &m.Values[i]) + offset += 12 + } + + if offset != m.Length { + return ErrPrismExpectedMoreData + } + + return nil +} + +func (m *PrismHeader) CanDecode() gopacket.LayerClass { return LayerTypePrismHeader } +func (m *PrismHeader) NextLayerType() gopacket.LayerType { return LayerTypeDot11 } diff --git a/vendor/github.com/google/gopacket/layers/prism_test.go b/vendor/github.com/google/gopacket/layers/prism_test.go new file mode 100644 index 0000000..136a04c --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/prism_test.go @@ -0,0 +1,120 @@ +// Copyright 2014, Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "net" + "reflect" + "testing" + + "github.com/google/gopacket" +) + +// Generator: python layers/test_creator.py --layerType=LayerTypePrismHeader --linkType=LinkTypePrismHeader --name=Prism%s ~/tmp/dump.pcap +// http://wiki.wireshark.org/SampleCaptures#Sample_Captures + +// testPacketPrism is the packet: +// 21:32:37.616872 BSSID:Broadcast DA:Broadcast SA:cc:fa:00:ad:79:e8 (oui Unknown) Probe Request () [1.0 2.0 5.5 11.0 Mbit] +// 0x0000: 4400 0000 9000 0000 7261 3000 0000 0000 +// 0x0010: 0000 0000 0000 0000 4400 0100 0000 0400 +// 0x0020: f9c1 2900 4400 0200 0000 0000 0000 0000 +// 0x0030: 4400 0300 0000 0400 0a00 0000 4400 0400 +// 0x0040: 0000 0400 e1ff ffff 0000 0000 0000 0000 +// 0x0050: 0000 0000 4400 0600 0000 0400 0000 0000 +// 0x0060: 4400 0700 0000 0400 0000 0000 4400 0800 +// 0x0070: 0000 0400 0200 0000 4400 0900 0000 0000 +// 0x0080: 0000 0000 4400 0a00 0000 0400 7e00 0000 +// 0x0090: 4000 0000 ffff ffff ffff ccfa 00ad 79e8 +// 0x00a0: ffff ffff ffff a041 0000 0104 0204 0b16 +// 0x00b0: 3208 0c12 1824 3048 606c 0301 012d 1a2d +// 0x00c0: 1117 ff00 0000 0000 0000 0000 0000 0000 +// 0x00d0: 0000 0000 0000 0000 007f 0800 0000 0000 +// 0x00e0: 0000 40dd 0900 1018 0200 0010 0000 dd1e +// 0x00f0: 0090 4c33 2d11 17ff 0000 0000 0000 0000 +// 0x0100: 0000 0000 0000 0000 0000 0000 0000 + +var testPacketPrism = []byte{ + 0x44, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x72, 0x61, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, + 0xf9, 0xc1, 0x29, 0x00, 0x44, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x44, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x04, 0x00, 0xe1, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x44, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x04, 0x00, 0x7e, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xfa, 0x00, 0xad, 0x79, 0xe8, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa0, 0x41, 0x00, 0x00, 0x01, 0x04, 0x02, 0x04, 0x0b, 0x16, + 0x32, 0x08, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c, 0x03, 0x01, 0x01, 0x2d, 0x1a, 0x2d, + 0x11, 0x17, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0xdd, 0x09, 0x00, 0x10, 0x18, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0xdd, 0x1e, + 0x00, 0x90, 0x4c, 0x33, 0x2d, 0x11, 0x17, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +} + +func TestPacketPrism(t *testing.T) { + p := gopacket.NewPacket(testPacketPrism, LinkTypePrismHeader, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypePrismHeader, LayerTypeDot11, LayerTypeDot11MgmtProbeReq}, t) + + if got, ok := p.Layer(LayerTypePrismHeader).(*PrismHeader); ok { + want := &PrismHeader{ + BaseLayer: BaseLayer{ + Contents: []uint8{0x44, 0x0, 0x0, 0x0, 0x90, 0x0, 0x0, 0x0, 0x72, 0x61, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x44, 0x0, 0x1, 0x0, 0x0, 0x0, 0x4, 0x0, 0xf9, 0xc1, 0x29, 0x0, 0x44, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x44, 0x0, 0x3, 0x0, 0x0, 0x0, 0x4, 0x0, 0xa, 0x0, 0x0, 0x0, 0x44, 0x0, 0x4, 0x0, 0x0, 0x0, 0x4, 0x0, 0xe1, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x44, 0x0, 0x6, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x44, 0x0, 0x7, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x44, 0x0, 0x8, 0x0, 0x0, 0x0, 0x4, 0x0, 0x2, 0x0, 0x0, 0x0, 0x44, 0x0, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x44, 0x0, 0xa, 0x0, 0x0, 0x0, 0x4, 0x0, 0x7e, 0x0, 0x0, 0x0}, + Payload: []uint8{0x40, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xfa, 0x0, 0xad, 0x79, 0xe8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa0, 0x41, 0x0, 0x0, 0x1, 0x4, 0x2, 0x4, 0xb, 0x16, 0x32, 0x8, 0xc, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c, 0x3, 0x1, 0x1, 0x2d, 0x1a, 0x2d, 0x11, 0x17, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0xdd, 0x9, 0x0, 0x10, 0x18, 0x2, 0x0, 0x0, 0x10, 0x0, 0x0, 0xdd, 0x1e, 0x0, 0x90, 0x4c, 0x33, 0x2d, 0x11, 0x17, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, Code: 0x44, Length: 0x90, DeviceName: "ra0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + Values: []PrismValue{ + PrismValue{DID: PrismDIDType1HostTime, Status: 0x0, Length: 0x4, Data: []uint8{0xf9, 0xc1, 0x29, 0x0}}, + PrismValue{DID: PrismDIDType1MACTime, Status: 0x0, Length: 0x0, Data: []uint8{}}, + PrismValue{DID: PrismDIDType1Channel, Status: 0x0, Length: 0x4, Data: []uint8{0xa, 0x0, 0x0, 0x0}}, + PrismValue{DID: PrismDIDType1RSSI, Status: 0x0, Length: 0x4, Data: []uint8{0xe1, 0xff, 0xff, 0xff}}, + PrismValue{DID: 0x0, Status: 0x0, Length: 0x0, Data: []uint8{}}, + PrismValue{DID: PrismDIDType1Signal, Status: 0x0, Length: 0x4, Data: []uint8{0x0, 0x0, 0x0, 0x0}}, + PrismValue{DID: PrismDIDType1Noise, Status: 0x0, Length: 0x4, Data: []uint8{0x0, 0x0, 0x0, 0x0}}, + PrismValue{DID: PrismDIDType1Rate, Status: 0x0, Length: 0x4, Data: []uint8{0x2, 0x0, 0x0, 0x0}}, + PrismValue{DID: PrismDIDType1TransmittedFrameIndicator, Status: 0x0, Length: 0x0, Data: []uint8{}}, + PrismValue{DID: PrismDIDType1FrameLength, Status: 0x0, Length: 0x4, Data: []uint8{0x7e, 0x0, 0x0, 0x0}}, + }, + } + + if !reflect.DeepEqual(got, want) { + t.Errorf("RadioTap packet processing failed:\ngot :\n%#v\n\nwant :\n%#v\n\n", got, want) + } + } + + if got, ok := p.Layer(LayerTypeDot11).(*Dot11); ok { + want := &Dot11{ + BaseLayer: BaseLayer{ + Contents: []uint8{0x40, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xfa, 0x0, 0xad, 0x79, 0xe8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa0, 0x41}, + Payload: []uint8{0x0, 0x0, 0x1, 0x4, 0x2, 0x4, 0xb, 0x16, 0x32, 0x8, 0xc, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c, 0x3, 0x1, 0x1, 0x2d, 0x1a, 0x2d, 0x11, 0x17, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0xdd, 0x9, 0x0, 0x10, 0x18, 0x2, 0x0, 0x0, 0x10, 0x0, 0x0, 0xdd, 0x1e, 0x0, 0x90, 0x4c, 0x33, 0x2d, 0x11, 0x17, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, + }, + Type: 0x10, + Proto: 0x0, + Flags: 0x0, + DurationID: 0x0, + Address1: net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + Address2: net.HardwareAddr{0xcc, 0xfa, 0x0, 0xad, 0x79, 0xe8}, + Address3: net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + Address4: net.HardwareAddr(nil), + SequenceNumber: 0x041a, + FragmentNumber: 0x0, + Checksum: 0x0, + } + + if !reflect.DeepEqual(got, want) { + t.Errorf("Dot11 packet processing failed:\ngot :\n%#v\n\nwant :\n%#v\n\n", got, want) + } + } +} + +func BenchmarkDecodePacketPrism(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketPrism, LinkTypePrismHeader, gopacket.NoCopy) + } +} diff --git a/vendor/github.com/google/gopacket/layers/radiotap.go b/vendor/github.com/google/gopacket/layers/radiotap.go new file mode 100644 index 0000000..4304e75 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/radiotap.go @@ -0,0 +1,1045 @@ +// Copyright 2014 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "bytes" + "encoding/binary" + "fmt" + "hash/crc32" + "strings" + + "github.com/google/gopacket" +) + +// align calculates the number of bytes needed to align with the width +// on the offset, returning the number of bytes we need to skip to +// align to the offset (width). +func align(offset uint16, width uint16) uint16 { + return ((((offset) + ((width) - 1)) & (^((width) - 1))) - offset) +} + +type RadioTapPresent uint32 + +const ( + RadioTapPresentTSFT RadioTapPresent = 1 << iota + RadioTapPresentFlags + RadioTapPresentRate + RadioTapPresentChannel + RadioTapPresentFHSS + RadioTapPresentDBMAntennaSignal + RadioTapPresentDBMAntennaNoise + RadioTapPresentLockQuality + RadioTapPresentTxAttenuation + RadioTapPresentDBTxAttenuation + RadioTapPresentDBMTxPower + RadioTapPresentAntenna + RadioTapPresentDBAntennaSignal + RadioTapPresentDBAntennaNoise + RadioTapPresentRxFlags + RadioTapPresentTxFlags + RadioTapPresentRtsRetries + RadioTapPresentDataRetries + _ + RadioTapPresentMCS + RadioTapPresentAMPDUStatus + RadioTapPresentVHT + RadioTapPresentEXT RadioTapPresent = 1 << 31 +) + +func (r RadioTapPresent) TSFT() bool { + return r&RadioTapPresentTSFT != 0 +} +func (r RadioTapPresent) Flags() bool { + return r&RadioTapPresentFlags != 0 +} +func (r RadioTapPresent) Rate() bool { + return r&RadioTapPresentRate != 0 +} +func (r RadioTapPresent) Channel() bool { + return r&RadioTapPresentChannel != 0 +} +func (r RadioTapPresent) FHSS() bool { + return r&RadioTapPresentFHSS != 0 +} +func (r RadioTapPresent) DBMAntennaSignal() bool { + return r&RadioTapPresentDBMAntennaSignal != 0 +} +func (r RadioTapPresent) DBMAntennaNoise() bool { + return r&RadioTapPresentDBMAntennaNoise != 0 +} +func (r RadioTapPresent) LockQuality() bool { + return r&RadioTapPresentLockQuality != 0 +} +func (r RadioTapPresent) TxAttenuation() bool { + return r&RadioTapPresentTxAttenuation != 0 +} +func (r RadioTapPresent) DBTxAttenuation() bool { + return r&RadioTapPresentDBTxAttenuation != 0 +} +func (r RadioTapPresent) DBMTxPower() bool { + return r&RadioTapPresentDBMTxPower != 0 +} +func (r RadioTapPresent) Antenna() bool { + return r&RadioTapPresentAntenna != 0 +} +func (r RadioTapPresent) DBAntennaSignal() bool { + return r&RadioTapPresentDBAntennaSignal != 0 +} +func (r RadioTapPresent) DBAntennaNoise() bool { + return r&RadioTapPresentDBAntennaNoise != 0 +} +func (r RadioTapPresent) RxFlags() bool { + return r&RadioTapPresentRxFlags != 0 +} +func (r RadioTapPresent) TxFlags() bool { + return r&RadioTapPresentTxFlags != 0 +} +func (r RadioTapPresent) RtsRetries() bool { + return r&RadioTapPresentRtsRetries != 0 +} +func (r RadioTapPresent) DataRetries() bool { + return r&RadioTapPresentDataRetries != 0 +} +func (r RadioTapPresent) MCS() bool { + return r&RadioTapPresentMCS != 0 +} +func (r RadioTapPresent) AMPDUStatus() bool { + return r&RadioTapPresentAMPDUStatus != 0 +} +func (r RadioTapPresent) VHT() bool { + return r&RadioTapPresentVHT != 0 +} +func (r RadioTapPresent) EXT() bool { + return r&RadioTapPresentEXT != 0 +} + +type RadioTapChannelFlags uint16 + +const ( + RadioTapChannelFlagsTurbo RadioTapChannelFlags = 0x0010 // Turbo channel + RadioTapChannelFlagsCCK RadioTapChannelFlags = 0x0020 // CCK channel + RadioTapChannelFlagsOFDM RadioTapChannelFlags = 0x0040 // OFDM channel + RadioTapChannelFlagsGhz2 RadioTapChannelFlags = 0x0080 // 2 GHz spectrum channel. + RadioTapChannelFlagsGhz5 RadioTapChannelFlags = 0x0100 // 5 GHz spectrum channel + RadioTapChannelFlagsPassive RadioTapChannelFlags = 0x0200 // Only passive scan allowed + RadioTapChannelFlagsDynamic RadioTapChannelFlags = 0x0400 // Dynamic CCK-OFDM channel + RadioTapChannelFlagsGFSK RadioTapChannelFlags = 0x0800 // GFSK channel (FHSS PHY) +) + +func (r RadioTapChannelFlags) Turbo() bool { + return r&RadioTapChannelFlagsTurbo != 0 +} +func (r RadioTapChannelFlags) CCK() bool { + return r&RadioTapChannelFlagsCCK != 0 +} +func (r RadioTapChannelFlags) OFDM() bool { + return r&RadioTapChannelFlagsOFDM != 0 +} +func (r RadioTapChannelFlags) Ghz2() bool { + return r&RadioTapChannelFlagsGhz2 != 0 +} +func (r RadioTapChannelFlags) Ghz5() bool { + return r&RadioTapChannelFlagsGhz5 != 0 +} +func (r RadioTapChannelFlags) Passive() bool { + return r&RadioTapChannelFlagsPassive != 0 +} +func (r RadioTapChannelFlags) Dynamic() bool { + return r&RadioTapChannelFlagsDynamic != 0 +} +func (r RadioTapChannelFlags) GFSK() bool { + return r&RadioTapChannelFlagsGFSK != 0 +} + +// String provides a human readable string for RadioTapChannelFlags. +// This string is possibly subject to change over time; if you're storing this +// persistently, you should probably store the RadioTapChannelFlags value, not its string. +func (a RadioTapChannelFlags) String() string { + var out bytes.Buffer + if a.Turbo() { + out.WriteString("Turbo,") + } + if a.CCK() { + out.WriteString("CCK,") + } + if a.OFDM() { + out.WriteString("OFDM,") + } + if a.Ghz2() { + out.WriteString("Ghz2,") + } + if a.Ghz5() { + out.WriteString("Ghz5,") + } + if a.Passive() { + out.WriteString("Passive,") + } + if a.Dynamic() { + out.WriteString("Dynamic,") + } + if a.GFSK() { + out.WriteString("GFSK,") + } + + if length := out.Len(); length > 0 { + return string(out.Bytes()[:length-1]) // strip final comma + } + return "" +} + +type RadioTapFlags uint8 + +const ( + RadioTapFlagsCFP RadioTapFlags = 1 << iota // sent/received during CFP + RadioTapFlagsShortPreamble // sent/received * with short * preamble + RadioTapFlagsWEP // sent/received * with WEP encryption + RadioTapFlagsFrag // sent/received * with fragmentation + RadioTapFlagsFCS // frame includes FCS + RadioTapFlagsDatapad // frame has padding between * 802.11 header and payload * (to 32-bit boundary) + RadioTapFlagsBadFCS // does not pass FCS check + RadioTapFlagsShortGI // HT short GI +) + +func (r RadioTapFlags) CFP() bool { + return r&RadioTapFlagsCFP != 0 +} +func (r RadioTapFlags) ShortPreamble() bool { + return r&RadioTapFlagsShortPreamble != 0 +} +func (r RadioTapFlags) WEP() bool { + return r&RadioTapFlagsWEP != 0 +} +func (r RadioTapFlags) Frag() bool { + return r&RadioTapFlagsFrag != 0 +} +func (r RadioTapFlags) FCS() bool { + return r&RadioTapFlagsFCS != 0 +} +func (r RadioTapFlags) Datapad() bool { + return r&RadioTapFlagsDatapad != 0 +} +func (r RadioTapFlags) BadFCS() bool { + return r&RadioTapFlagsBadFCS != 0 +} +func (r RadioTapFlags) ShortGI() bool { + return r&RadioTapFlagsShortGI != 0 +} + +// String provides a human readable string for RadioTapFlags. +// This string is possibly subject to change over time; if you're storing this +// persistently, you should probably store the RadioTapFlags value, not its string. +func (a RadioTapFlags) String() string { + var out bytes.Buffer + if a.CFP() { + out.WriteString("CFP,") + } + if a.ShortPreamble() { + out.WriteString("SHORT-PREAMBLE,") + } + if a.WEP() { + out.WriteString("WEP,") + } + if a.Frag() { + out.WriteString("FRAG,") + } + if a.FCS() { + out.WriteString("FCS,") + } + if a.Datapad() { + out.WriteString("DATAPAD,") + } + if a.ShortGI() { + out.WriteString("SHORT-GI,") + } + + if length := out.Len(); length > 0 { + return string(out.Bytes()[:length-1]) // strip final comma + } + return "" +} + +type RadioTapRate uint8 + +func (a RadioTapRate) String() string { + return fmt.Sprintf("%v Mb/s", 0.5*float32(a)) +} + +type RadioTapChannelFrequency uint16 + +func (a RadioTapChannelFrequency) String() string { + return fmt.Sprintf("%d MHz", a) +} + +type RadioTapRxFlags uint16 + +const ( + RadioTapRxFlagsBadPlcp RadioTapRxFlags = 0x0002 +) + +func (self RadioTapRxFlags) BadPlcp() bool { + return self&RadioTapRxFlagsBadPlcp != 0 +} + +func (self RadioTapRxFlags) String() string { + if self.BadPlcp() { + return "BADPLCP" + } + return "" +} + +type RadioTapTxFlags uint16 + +const ( + RadioTapTxFlagsFail RadioTapTxFlags = 1 << iota + RadioTapTxFlagsCTS + RadioTapTxFlagsRTS + RadioTapTxFlagsNoACK +) + +func (self RadioTapTxFlags) Fail() bool { return self&RadioTapTxFlagsFail != 0 } +func (self RadioTapTxFlags) CTS() bool { return self&RadioTapTxFlagsCTS != 0 } +func (self RadioTapTxFlags) RTS() bool { return self&RadioTapTxFlagsRTS != 0 } +func (self RadioTapTxFlags) NoACK() bool { return self&RadioTapTxFlagsNoACK != 0 } + +func (self RadioTapTxFlags) String() string { + var tokens []string + if self.Fail() { + tokens = append(tokens, "Fail") + } + if self.CTS() { + tokens = append(tokens, "CTS") + } + if self.RTS() { + tokens = append(tokens, "RTS") + } + if self.NoACK() { + tokens = append(tokens, "NoACK") + } + return strings.Join(tokens, ",") +} + +type RadioTapMCS struct { + Known RadioTapMCSKnown + Flags RadioTapMCSFlags + MCS uint8 +} + +func (self RadioTapMCS) String() string { + var tokens []string + if self.Known.Bandwidth() { + token := "?" + switch self.Flags.Bandwidth() { + case 0: + token = "20" + case 1: + token = "40" + case 2: + token = "40(20L)" + case 3: + token = "40(20U)" + } + tokens = append(tokens, token) + } + if self.Known.MCSIndex() { + tokens = append(tokens, fmt.Sprintf("MCSIndex#%d", self.MCS)) + } + if self.Known.GuardInterval() { + if self.Flags.ShortGI() { + tokens = append(tokens, fmt.Sprintf("shortGI")) + } else { + tokens = append(tokens, fmt.Sprintf("longGI")) + } + } + if self.Known.HTFormat() { + if self.Flags.Greenfield() { + tokens = append(tokens, fmt.Sprintf("HT-greenfield")) + } else { + tokens = append(tokens, fmt.Sprintf("HT-mixed")) + } + } + if self.Known.FECType() { + if self.Flags.FECLDPC() { + tokens = append(tokens, fmt.Sprintf("LDPC")) + } else { + tokens = append(tokens, fmt.Sprintf("BCC")) + } + } + if self.Known.STBC() { + tokens = append(tokens, fmt.Sprintf("STBC#%d", self.Flags.STBC())) + } + if self.Known.NESS() { + num := 0 + if self.Known.NESS1() { + num |= 0x02 + } + if self.Flags.NESS0() { + num |= 0x01 + } + tokens = append(tokens, fmt.Sprintf("num-of-ESS#%d", num)) + } + return strings.Join(tokens, ",") +} + +type RadioTapMCSKnown uint8 + +const ( + RadioTapMCSKnownBandwidth RadioTapMCSKnown = 1 << iota + RadioTapMCSKnownMCSIndex + RadioTapMCSKnownGuardInterval + RadioTapMCSKnownHTFormat + RadioTapMCSKnownFECType + RadioTapMCSKnownSTBC + RadioTapMCSKnownNESS + RadioTapMCSKnownNESS1 +) + +func (self RadioTapMCSKnown) Bandwidth() bool { return self&RadioTapMCSKnownBandwidth != 0 } +func (self RadioTapMCSKnown) MCSIndex() bool { return self&RadioTapMCSKnownMCSIndex != 0 } +func (self RadioTapMCSKnown) GuardInterval() bool { return self&RadioTapMCSKnownGuardInterval != 0 } +func (self RadioTapMCSKnown) HTFormat() bool { return self&RadioTapMCSKnownHTFormat != 0 } +func (self RadioTapMCSKnown) FECType() bool { return self&RadioTapMCSKnownFECType != 0 } +func (self RadioTapMCSKnown) STBC() bool { return self&RadioTapMCSKnownSTBC != 0 } +func (self RadioTapMCSKnown) NESS() bool { return self&RadioTapMCSKnownNESS != 0 } +func (self RadioTapMCSKnown) NESS1() bool { return self&RadioTapMCSKnownNESS1 != 0 } + +type RadioTapMCSFlags uint8 + +const ( + RadioTapMCSFlagsBandwidthMask RadioTapMCSFlags = 0x03 + RadioTapMCSFlagsShortGI = 0x04 + RadioTapMCSFlagsGreenfield = 0x08 + RadioTapMCSFlagsFECLDPC = 0x10 + RadioTapMCSFlagsSTBCMask = 0x60 + RadioTapMCSFlagsNESS0 = 0x80 +) + +func (self RadioTapMCSFlags) Bandwidth() int { + return int(self & RadioTapMCSFlagsBandwidthMask) +} +func (self RadioTapMCSFlags) ShortGI() bool { return self&RadioTapMCSFlagsShortGI != 0 } +func (self RadioTapMCSFlags) Greenfield() bool { return self&RadioTapMCSFlagsGreenfield != 0 } +func (self RadioTapMCSFlags) FECLDPC() bool { return self&RadioTapMCSFlagsFECLDPC != 0 } +func (self RadioTapMCSFlags) STBC() int { + return int(self&RadioTapMCSFlagsSTBCMask) >> 5 +} +func (self RadioTapMCSFlags) NESS0() bool { return self&RadioTapMCSFlagsNESS0 != 0 } + +type RadioTapAMPDUStatus struct { + Reference uint32 + Flags RadioTapAMPDUStatusFlags + CRC uint8 +} + +func (self RadioTapAMPDUStatus) String() string { + tokens := []string{ + fmt.Sprintf("ref#%x", self.Reference), + } + if self.Flags.ReportZerolen() && self.Flags.IsZerolen() { + tokens = append(tokens, fmt.Sprintf("zero-length")) + } + if self.Flags.LastKnown() && self.Flags.IsLast() { + tokens = append(tokens, "last") + } + if self.Flags.DelimCRCErr() { + tokens = append(tokens, "delimiter CRC error") + } + if self.Flags.DelimCRCKnown() { + tokens = append(tokens, fmt.Sprintf("delimiter-CRC=%02x", self.CRC)) + } + return strings.Join(tokens, ",") +} + +type RadioTapAMPDUStatusFlags uint16 + +const ( + RadioTapAMPDUStatusFlagsReportZerolen RadioTapAMPDUStatusFlags = 1 << iota + RadioTapAMPDUIsZerolen + RadioTapAMPDULastKnown + RadioTapAMPDUIsLast + RadioTapAMPDUDelimCRCErr + RadioTapAMPDUDelimCRCKnown +) + +func (self RadioTapAMPDUStatusFlags) ReportZerolen() bool { + return self&RadioTapAMPDUStatusFlagsReportZerolen != 0 +} +func (self RadioTapAMPDUStatusFlags) IsZerolen() bool { return self&RadioTapAMPDUIsZerolen != 0 } +func (self RadioTapAMPDUStatusFlags) LastKnown() bool { return self&RadioTapAMPDULastKnown != 0 } +func (self RadioTapAMPDUStatusFlags) IsLast() bool { return self&RadioTapAMPDUIsLast != 0 } +func (self RadioTapAMPDUStatusFlags) DelimCRCErr() bool { return self&RadioTapAMPDUDelimCRCErr != 0 } +func (self RadioTapAMPDUStatusFlags) DelimCRCKnown() bool { return self&RadioTapAMPDUDelimCRCKnown != 0 } + +type RadioTapVHT struct { + Known RadioTapVHTKnown + Flags RadioTapVHTFlags + Bandwidth uint8 + MCSNSS [4]RadioTapVHTMCSNSS + Coding uint8 + GroupId uint8 + PartialAID uint16 +} + +func (self RadioTapVHT) String() string { + var tokens []string + if self.Known.STBC() { + if self.Flags.STBC() { + tokens = append(tokens, "STBC") + } else { + tokens = append(tokens, "no STBC") + } + } + if self.Known.TXOPPSNotAllowed() { + if self.Flags.TXOPPSNotAllowed() { + tokens = append(tokens, "TXOP doze not allowed") + } else { + tokens = append(tokens, "TXOP doze allowed") + } + } + if self.Known.GI() { + if self.Flags.SGI() { + tokens = append(tokens, "short GI") + } else { + tokens = append(tokens, "long GI") + } + } + if self.Known.SGINSYMDisambiguation() { + if self.Flags.SGINSYMMod() { + tokens = append(tokens, "NSYM mod 10=9") + } else { + tokens = append(tokens, "NSYM mod 10!=9 or no short GI") + } + } + if self.Known.LDPCExtraOFDMSymbol() { + if self.Flags.LDPCExtraOFDMSymbol() { + tokens = append(tokens, "LDPC extra OFDM symbols") + } else { + tokens = append(tokens, "no LDPC extra OFDM symbols") + } + } + if self.Known.Beamformed() { + if self.Flags.Beamformed() { + tokens = append(tokens, "beamformed") + } else { + tokens = append(tokens, "no beamformed") + } + } + if self.Known.Bandwidth() { + token := "?" + switch self.Bandwidth & 0x1f { + case 0: + token = "20" + case 1: + token = "40" + case 2: + token = "40(20L)" + case 3: + token = "40(20U)" + case 4: + token = "80" + case 5: + token = "80(40L)" + case 6: + token = "80(40U)" + case 7: + token = "80(20LL)" + case 8: + token = "80(20LU)" + case 9: + token = "80(20UL)" + case 10: + token = "80(20UU)" + case 11: + token = "160" + case 12: + token = "160(80L)" + case 13: + token = "160(80U)" + case 14: + token = "160(40LL)" + case 15: + token = "160(40LU)" + case 16: + token = "160(40UL)" + case 17: + token = "160(40UU)" + case 18: + token = "160(20LLL)" + case 19: + token = "160(20LLU)" + case 20: + token = "160(20LUL)" + case 21: + token = "160(20LUU)" + case 22: + token = "160(20ULL)" + case 23: + token = "160(20ULU)" + case 24: + token = "160(20UUL)" + case 25: + token = "160(20UUU)" + } + tokens = append(tokens, token) + } + for i, MCSNSS := range self.MCSNSS { + if MCSNSS.Present() { + fec := "?" + switch self.Coding & (1 << uint8(i)) { + case 0: + fec = "BCC" + case 1: + fec = "LDPC" + } + tokens = append(tokens, fmt.Sprintf("user%d(%s,%s)", i, MCSNSS.String(), fec)) + } + } + if self.Known.GroupId() { + tokens = append(tokens, + fmt.Sprintf("group=%d", self.GroupId)) + } + if self.Known.PartialAID() { + tokens = append(tokens, + fmt.Sprintf("partial-AID=%d", self.PartialAID)) + } + return strings.Join(tokens, ",") +} + +type RadioTapVHTKnown uint16 + +const ( + RadioTapVHTKnownSTBC RadioTapVHTKnown = 1 << iota + RadioTapVHTKnownTXOPPSNotAllowed + RadioTapVHTKnownGI + RadioTapVHTKnownSGINSYMDisambiguation + RadioTapVHTKnownLDPCExtraOFDMSymbol + RadioTapVHTKnownBeamformed + RadioTapVHTKnownBandwidth + RadioTapVHTKnownGroupId + RadioTapVHTKnownPartialAID +) + +func (self RadioTapVHTKnown) STBC() bool { return self&RadioTapVHTKnownSTBC != 0 } +func (self RadioTapVHTKnown) TXOPPSNotAllowed() bool { + return self&RadioTapVHTKnownTXOPPSNotAllowed != 0 +} +func (self RadioTapVHTKnown) GI() bool { return self&RadioTapVHTKnownGI != 0 } +func (self RadioTapVHTKnown) SGINSYMDisambiguation() bool { + return self&RadioTapVHTKnownSGINSYMDisambiguation != 0 +} +func (self RadioTapVHTKnown) LDPCExtraOFDMSymbol() bool { + return self&RadioTapVHTKnownLDPCExtraOFDMSymbol != 0 +} +func (self RadioTapVHTKnown) Beamformed() bool { return self&RadioTapVHTKnownBeamformed != 0 } +func (self RadioTapVHTKnown) Bandwidth() bool { return self&RadioTapVHTKnownBandwidth != 0 } +func (self RadioTapVHTKnown) GroupId() bool { return self&RadioTapVHTKnownGroupId != 0 } +func (self RadioTapVHTKnown) PartialAID() bool { return self&RadioTapVHTKnownPartialAID != 0 } + +type RadioTapVHTFlags uint8 + +const ( + RadioTapVHTFlagsSTBC RadioTapVHTFlags = 1 << iota + RadioTapVHTFlagsTXOPPSNotAllowed + RadioTapVHTFlagsSGI + RadioTapVHTFlagsSGINSYMMod + RadioTapVHTFlagsLDPCExtraOFDMSymbol + RadioTapVHTFlagsBeamformed +) + +func (self RadioTapVHTFlags) STBC() bool { return self&RadioTapVHTFlagsSTBC != 0 } +func (self RadioTapVHTFlags) TXOPPSNotAllowed() bool { + return self&RadioTapVHTFlagsTXOPPSNotAllowed != 0 +} +func (self RadioTapVHTFlags) SGI() bool { return self&RadioTapVHTFlagsSGI != 0 } +func (self RadioTapVHTFlags) SGINSYMMod() bool { return self&RadioTapVHTFlagsSGINSYMMod != 0 } +func (self RadioTapVHTFlags) LDPCExtraOFDMSymbol() bool { + return self&RadioTapVHTFlagsLDPCExtraOFDMSymbol != 0 +} +func (self RadioTapVHTFlags) Beamformed() bool { return self&RadioTapVHTFlagsBeamformed != 0 } + +type RadioTapVHTMCSNSS uint8 + +func (self RadioTapVHTMCSNSS) Present() bool { + return self&0x0F != 0 +} + +func (self RadioTapVHTMCSNSS) String() string { + return fmt.Sprintf("NSS#%dMCS#%d", uint32(self&0xf), uint32(self>>4)) +} + +func decodeRadioTap(data []byte, p gopacket.PacketBuilder) error { + d := &RadioTap{} + // TODO: Should we set LinkLayer here? And implement LinkFlow + return decodingLayerDecoder(d, data, p) +} + +type RadioTap struct { + BaseLayer + + // Version 0. Only increases for drastic changes, introduction of compatible new fields does not count. + Version uint8 + // Length of the whole header in bytes, including it_version, it_pad, it_len, and data fields. + Length uint16 + // Present is a bitmap telling which fields are present. Set bit 31 (0x80000000) to extend the bitmap by another 32 bits. Additional extensions are made by setting bit 31. + Present RadioTapPresent + // TSFT: value in microseconds of the MAC's 64-bit 802.11 Time Synchronization Function timer when the first bit of the MPDU arrived at the MAC. For received frames, only. + TSFT uint64 + Flags RadioTapFlags + // Rate Tx/Rx data rate + Rate RadioTapRate + // ChannelFrequency Tx/Rx frequency in MHz, followed by flags + ChannelFrequency RadioTapChannelFrequency + ChannelFlags RadioTapChannelFlags + // FHSS For frequency-hopping radios, the hop set (first byte) and pattern (second byte). + FHSS uint16 + // DBMAntennaSignal RF signal power at the antenna, decibel difference from one milliwatt. + DBMAntennaSignal int8 + // DBMAntennaNoise RF noise power at the antenna, decibel difference from one milliwatt. + DBMAntennaNoise int8 + // LockQuality Quality of Barker code lock. Unitless. Monotonically nondecreasing with "better" lock strength. Called "Signal Quality" in datasheets. + LockQuality uint16 + // TxAttenuation Transmit power expressed as unitless distance from max power set at factory calibration. 0 is max power. Monotonically nondecreasing with lower power levels. + TxAttenuation uint16 + // DBTxAttenuation Transmit power expressed as decibel distance from max power set at factory calibration. 0 is max power. Monotonically nondecreasing with lower power levels. + DBTxAttenuation uint16 + // DBMTxPower Transmit power expressed as dBm (decibels from a 1 milliwatt reference). This is the absolute power level measured at the antenna port. + DBMTxPower int8 + // Antenna Unitless indication of the Rx/Tx antenna for this packet. The first antenna is antenna 0. + Antenna uint8 + // DBAntennaSignal RF signal power at the antenna, decibel difference from an arbitrary, fixed reference. + DBAntennaSignal uint8 + // DBAntennaNoise RF noise power at the antenna, decibel difference from an arbitrary, fixed reference point. + DBAntennaNoise uint8 + // + RxFlags RadioTapRxFlags + TxFlags RadioTapTxFlags + RtsRetries uint8 + DataRetries uint8 + MCS RadioTapMCS + AMPDUStatus RadioTapAMPDUStatus + VHT RadioTapVHT +} + +func (m *RadioTap) LayerType() gopacket.LayerType { return LayerTypeRadioTap } + +func (m *RadioTap) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + m.Version = uint8(data[0]) + m.Length = binary.LittleEndian.Uint16(data[2:4]) + m.Present = RadioTapPresent(binary.LittleEndian.Uint32(data[4:8])) + + offset := uint16(4) + + for (binary.LittleEndian.Uint32(data[offset:offset+4]) & 0x80000000) != 0 { + // This parser only handles standard radiotap namespace, + // and expects all fields are packed in the first it_present. + // Extended bitmap will be just ignored. + offset += 4 + } + offset += 4 // skip the bitmap + + if m.Present.TSFT() { + offset += align(offset, 8) + m.TSFT = binary.LittleEndian.Uint64(data[offset : offset+8]) + offset += 8 + } + if m.Present.Flags() { + m.Flags = RadioTapFlags(data[offset]) + offset++ + } + if m.Present.Rate() { + m.Rate = RadioTapRate(data[offset]) + offset++ + } + if m.Present.Channel() { + offset += align(offset, 2) + m.ChannelFrequency = RadioTapChannelFrequency(binary.LittleEndian.Uint16(data[offset : offset+2])) + offset += 2 + m.ChannelFlags = RadioTapChannelFlags(binary.LittleEndian.Uint16(data[offset : offset+2])) + offset += 2 + } + if m.Present.FHSS() { + m.FHSS = binary.LittleEndian.Uint16(data[offset : offset+2]) + offset += 2 + } + if m.Present.DBMAntennaSignal() { + m.DBMAntennaSignal = int8(data[offset]) + offset++ + } + if m.Present.DBMAntennaNoise() { + m.DBMAntennaNoise = int8(data[offset]) + offset++ + } + if m.Present.LockQuality() { + offset += align(offset, 2) + m.LockQuality = binary.LittleEndian.Uint16(data[offset : offset+2]) + offset += 2 + } + if m.Present.TxAttenuation() { + offset += align(offset, 2) + m.TxAttenuation = binary.LittleEndian.Uint16(data[offset : offset+2]) + offset += 2 + } + if m.Present.DBTxAttenuation() { + offset += align(offset, 2) + m.DBTxAttenuation = binary.LittleEndian.Uint16(data[offset : offset+2]) + offset += 2 + } + if m.Present.DBMTxPower() { + m.DBMTxPower = int8(data[offset]) + offset++ + } + if m.Present.Antenna() { + m.Antenna = uint8(data[offset]) + offset++ + } + if m.Present.DBAntennaSignal() { + m.DBAntennaSignal = uint8(data[offset]) + offset++ + } + if m.Present.DBAntennaNoise() { + m.DBAntennaNoise = uint8(data[offset]) + offset++ + } + if m.Present.RxFlags() { + offset += align(offset, 2) + m.RxFlags = RadioTapRxFlags(binary.LittleEndian.Uint16(data[offset:])) + offset += 2 + } + if m.Present.TxFlags() { + offset += align(offset, 2) + m.TxFlags = RadioTapTxFlags(binary.LittleEndian.Uint16(data[offset:])) + offset += 2 + } + if m.Present.RtsRetries() { + m.RtsRetries = uint8(data[offset]) + offset++ + } + if m.Present.DataRetries() { + m.DataRetries = uint8(data[offset]) + offset++ + } + if m.Present.MCS() { + m.MCS = RadioTapMCS{ + RadioTapMCSKnown(data[offset]), + RadioTapMCSFlags(data[offset+1]), + uint8(data[offset+2]), + } + offset += 3 + } + if m.Present.AMPDUStatus() { + offset += align(offset, 4) + m.AMPDUStatus = RadioTapAMPDUStatus{ + Reference: binary.LittleEndian.Uint32(data[offset:]), + Flags: RadioTapAMPDUStatusFlags(binary.LittleEndian.Uint16(data[offset+4:])), + CRC: uint8(data[offset+6]), + } + offset += 8 + } + if m.Present.VHT() { + offset += align(offset, 2) + m.VHT = RadioTapVHT{ + Known: RadioTapVHTKnown(binary.LittleEndian.Uint16(data[offset:])), + Flags: RadioTapVHTFlags(data[offset+2]), + Bandwidth: uint8(data[offset+3]), + MCSNSS: [4]RadioTapVHTMCSNSS{ + RadioTapVHTMCSNSS(data[offset+4]), + RadioTapVHTMCSNSS(data[offset+5]), + RadioTapVHTMCSNSS(data[offset+6]), + RadioTapVHTMCSNSS(data[offset+7]), + }, + Coding: uint8(data[offset+8]), + GroupId: uint8(data[offset+9]), + PartialAID: binary.LittleEndian.Uint16(data[offset+10:]), + } + offset += 12 + } + + payload := data[m.Length:] + if !m.Flags.FCS() { // Dot11.DecodeFromBytes() expects FCS present + fcs := make([]byte, 4) + h := crc32.NewIEEE() + h.Write(payload) + binary.LittleEndian.PutUint32(fcs, h.Sum32()) + payload = append(payload, fcs...) + } + m.BaseLayer = BaseLayer{Contents: data[:m.Length], Payload: payload} + + return nil +} + +func (m RadioTap) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + buf := make([]byte, 1024) + + buf[0] = m.Version + buf[1] = 0 + + binary.LittleEndian.PutUint32(buf[4:8], uint32(m.Present)) + + offset := uint16(4) + + for (binary.LittleEndian.Uint32(buf[offset:offset+4]) & 0x80000000) != 0 { + offset += 4 + } + + offset += 4 + + if m.Present.TSFT() { + offset += align(offset, 8) + binary.LittleEndian.PutUint64(buf[offset:offset+8], m.TSFT) + offset += 8 + } + + if m.Present.Flags() { + buf[offset] = uint8(m.Flags) + offset++ + } + + if m.Present.Rate() { + buf[offset] = uint8(m.Rate) + offset++ + } + + if m.Present.Channel() { + offset += align(offset, 2) + binary.LittleEndian.PutUint16(buf[offset:offset+2], uint16(m.ChannelFrequency)) + offset += 2 + binary.LittleEndian.PutUint16(buf[offset:offset+2], uint16(m.ChannelFlags)) + offset += 2 + } + + if m.Present.FHSS() { + binary.LittleEndian.PutUint16(buf[offset:offset+2], m.FHSS) + offset += 2 + } + + if m.Present.DBMAntennaSignal() { + buf[offset] = byte(m.DBMAntennaSignal) + offset++ + } + + if m.Present.DBMAntennaNoise() { + buf[offset] = byte(m.DBMAntennaNoise) + offset++ + } + + if m.Present.LockQuality() { + offset += align(offset, 2) + binary.LittleEndian.PutUint16(buf[offset:offset+2], m.LockQuality) + offset += 2 + } + + if m.Present.TxAttenuation() { + offset += align(offset, 2) + binary.LittleEndian.PutUint16(buf[offset:offset+2], m.TxAttenuation) + offset += 2 + } + + if m.Present.DBTxAttenuation() { + offset += align(offset, 2) + binary.LittleEndian.PutUint16(buf[offset:offset+2], m.DBTxAttenuation) + offset += 2 + } + + if m.Present.DBMTxPower() { + buf[offset] = byte(m.DBMTxPower) + offset++ + } + + if m.Present.Antenna() { + buf[offset] = uint8(m.Antenna) + offset++ + } + + if m.Present.DBAntennaSignal() { + buf[offset] = uint8(m.DBAntennaSignal) + offset++ + } + + if m.Present.DBAntennaNoise() { + buf[offset] = uint8(m.DBAntennaNoise) + offset++ + } + + if m.Present.RxFlags() { + offset += align(offset, 2) + binary.LittleEndian.PutUint16(buf[offset:offset+2], uint16(m.RxFlags)) + offset += 2 + } + + if m.Present.TxFlags() { + offset += align(offset, 2) + binary.LittleEndian.PutUint16(buf[offset:offset+2], uint16(m.TxFlags)) + offset += 2 + } + + if m.Present.RtsRetries() { + buf[offset] = m.RtsRetries + offset++ + } + + if m.Present.DataRetries() { + buf[offset] = m.DataRetries + offset++ + } + + if m.Present.MCS() { + buf[offset] = uint8(m.MCS.Known) + buf[offset+1] = uint8(m.MCS.Flags) + buf[offset+2] = uint8(m.MCS.MCS) + + offset += 3 + } + + if m.Present.AMPDUStatus() { + offset += align(offset, 4) + + binary.LittleEndian.PutUint32(buf[offset:offset+4], m.AMPDUStatus.Reference) + binary.LittleEndian.PutUint16(buf[offset+4:offset+6], uint16(m.AMPDUStatus.Flags)) + + buf[offset+6] = m.AMPDUStatus.CRC + + offset += 8 + } + + if m.Present.VHT() { + offset += align(offset, 2) + + binary.LittleEndian.PutUint16(buf[offset:], uint16(m.VHT.Known)) + + buf[offset+2] = uint8(m.VHT.Flags) + buf[offset+3] = uint8(m.VHT.Bandwidth) + buf[offset+4] = uint8(m.VHT.MCSNSS[0]) + buf[offset+5] = uint8(m.VHT.MCSNSS[1]) + buf[offset+6] = uint8(m.VHT.MCSNSS[2]) + buf[offset+7] = uint8(m.VHT.MCSNSS[3]) + buf[offset+8] = uint8(m.VHT.Coding) + buf[offset+9] = uint8(m.VHT.GroupId) + + binary.LittleEndian.PutUint16(buf[offset+10:offset+12], m.VHT.PartialAID) + + offset += 12 + } + + packetBuf, err := b.PrependBytes(int(offset)) + + if err != nil { + return err + } + + if opts.FixLengths { + m.Length = offset + } + + binary.LittleEndian.PutUint16(buf[2:4], m.Length) + + copy(packetBuf, buf) + + return nil +} + +func (m *RadioTap) CanDecode() gopacket.LayerClass { return LayerTypeRadioTap } +func (m *RadioTap) NextLayerType() gopacket.LayerType { return LayerTypeDot11 } diff --git a/vendor/github.com/google/gopacket/layers/radiotap_test.go b/vendor/github.com/google/gopacket/layers/radiotap_test.go new file mode 100644 index 0000000..4d3c7d0 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/radiotap_test.go @@ -0,0 +1,79 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. +package layers + +import ( + "github.com/google/gopacket" + "testing" +) + +// testPacketRadiotap0 is the packet: +// 09:34:34.799438 1.0 Mb/s 2412 MHz 11b -58dB signal antenna 7 Acknowledgment RA:88:1f:a1:ae:9d:cb +// 0x0000: 0000 1200 2e48 0000 1002 6c09 a000 c607 .....H....l..... +// 0x0010: 0000 d400 0000 881f a1ae 9dcb c630 4b4b .............0KK +var testPacketRadiotap0 = []byte{ + 0x00, 0x00, 0x12, 0x00, 0x2e, 0x48, 0x00, 0x00, 0x10, 0x02, 0x6c, 0x09, 0xa0, 0x00, 0xc6, 0x07, + 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x88, 0x1f, 0xa1, 0xae, 0x9d, 0xcb, 0xc6, 0x30, 0x4b, 0x4b, +} + +func TestPacketRadiotap0(t *testing.T) { + p := gopacket.NewPacket(testPacketRadiotap0, LayerTypeRadioTap, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeRadioTap, LayerTypeDot11}, t) + rt := p.Layer(LayerTypeRadioTap).(*RadioTap) + if rt.ChannelFrequency != 2412 || rt.DBMAntennaSignal != -58 || rt.Antenna != 7 { + t.Error("Radiotap decode error") + } + if rt.Rate != 2 { // 500Kbps unit + t.Error("Radiotap Rate decode error") + } +} +func BenchmarkDecodePacketRadiotap0(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketRadiotap0, LayerTypeRadioTap, gopacket.NoCopy) + } +} + +// testPacketRadiotap1 is the packet: +// 05:24:21.380948 2412 MHz 11g -36dB signal antenna 5 65.0 Mb/s MCS 7 20 MHz lon GI +// 0x0000: 0000 1500 2a48 0800 1000 6c09 8004 dc05 ....*H....l..... +// 0x0010: 0000 0700 0748 112c 0000 3a9d aaf0 191c .....H.,..:..... +// 0x0020: aba7 f213 9d00 3a9d aaf0 1970 b2ee a9f1 ......:....p.... +// 0x0030: 16 . +var testPacketRadiotap1 = []byte{ + 0x00, 0x00, 0x15, 0x00, 0x2a, 0x48, 0x08, 0x00, 0x10, 0x00, 0x6c, 0x09, 0x80, 0x04, 0xdc, 0x05, + 0x00, 0x00, 0x07, 0x00, 0x07, 0x48, 0x11, 0x2c, 0x00, 0x00, 0x3a, 0x9d, 0xaa, 0xf0, 0x19, 0x1c, + 0xab, 0xa7, 0xf2, 0x13, 0x9d, 0x00, 0x3a, 0x9d, 0xaa, 0xf0, 0x19, 0x70, 0xb2, 0xee, 0xa9, 0xf1, + 0x16, +} + +func TestPacketRadiotap1(t *testing.T) { + p := gopacket.NewPacket(testPacketRadiotap1, LayerTypeRadioTap, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeRadioTap, LayerTypeDot11}, t) + rt := p.Layer(LayerTypeRadioTap).(*RadioTap) + if rt.ChannelFrequency != 2412 || rt.DBMAntennaSignal != -36 || rt.Antenna != 5 { + t.Error("Radiotap decode error") + } + if !rt.MCS.Known.MCSIndex() || rt.MCS.MCS != 7 { + t.Error("Radiotap MCS error") + } + if !rt.MCS.Known.Bandwidth() || rt.MCS.Flags.Bandwidth() != 0 { + t.Error("Radiotap bandwidth error") + } + if !rt.MCS.Known.GuardInterval() || rt.MCS.Flags.ShortGI() { + t.Error("Radiotap GI error") + } +} +func BenchmarkDecodePacketRadiotap1(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketRadiotap1, LayerTypeRadioTap, gopacket.NoCopy) + } +} diff --git a/vendor/github.com/google/gopacket/layers/rudp.go b/vendor/github.com/google/gopacket/layers/rudp.go new file mode 100644 index 0000000..8435129 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/rudp.go @@ -0,0 +1,93 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "fmt" + "github.com/google/gopacket" +) + +type RUDP struct { + BaseLayer + SYN, ACK, EACK, RST, NUL bool + Version uint8 + HeaderLength uint8 + SrcPort, DstPort RUDPPort + DataLength uint16 + Seq, Ack, Checksum uint32 + VariableHeaderArea []byte + // RUDPHeaderSyn contains SYN information for the RUDP packet, + // if the SYN flag is set + *RUDPHeaderSYN + // RUDPHeaderEack contains EACK information for the RUDP packet, + // if the EACK flag is set. + *RUDPHeaderEACK +} + +type RUDPHeaderSYN struct { + MaxOutstandingSegments, MaxSegmentSize, OptionFlags uint16 +} + +type RUDPHeaderEACK struct { + SeqsReceivedOK []uint32 +} + +// LayerType returns gopacket.LayerTypeRUDP. +func (r *RUDP) LayerType() gopacket.LayerType { return LayerTypeRUDP } + +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 (r *RUDP) TransportFlow() gopacket.Flow { + return gopacket.NewFlow(EndpointRUDPPort, []byte{byte(r.SrcPort)}, []byte{byte(r.DstPort)}) +} diff --git a/vendor/github.com/google/gopacket/layers/sctp.go b/vendor/github.com/google/gopacket/layers/sctp.go new file mode 100644 index 0000000..511176e --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/sctp.go @@ -0,0 +1,746 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "errors" + "fmt" + "hash/crc32" + + "github.com/google/gopacket" +) + +// SCTP contains information on the top level of an SCTP packet. +type SCTP struct { + BaseLayer + SrcPort, DstPort SCTPPort + VerificationTag uint32 + Checksum uint32 + sPort, dPort []byte +} + +// LayerType returns gopacket.LayerTypeSCTP +func (s *SCTP) LayerType() gopacket.LayerType { return LayerTypeSCTP } + +func decodeSCTP(data []byte, p gopacket.PacketBuilder) error { + sctp := &SCTP{} + err := sctp.DecodeFromBytes(data, p) + p.AddLayer(sctp) + p.SetTransportLayer(sctp) + if err != nil { + return err + } + return p.NextDecoder(sctpChunkTypePrefixDecoder) +} + +var sctpChunkTypePrefixDecoder = gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix) + +// TransportFlow returns a flow based on the source and destination SCTP port. +func (s *SCTP) TransportFlow() gopacket.Flow { + return gopacket.NewFlow(EndpointSCTPPort, s.sPort, s.dPort) +} + +func decodeWithSCTPChunkTypePrefix(data []byte, p gopacket.PacketBuilder) error { + chunkType := SCTPChunkType(data[0]) + return chunkType.Decode(data, p) +} + +// SerializeTo is for gopacket.SerializableLayer. +func (s SCTP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + bytes, err := b.PrependBytes(12) + if err != nil { + return err + } + binary.BigEndian.PutUint16(bytes[0:2], uint16(s.SrcPort)) + binary.BigEndian.PutUint16(bytes[2:4], uint16(s.DstPort)) + binary.BigEndian.PutUint32(bytes[4:8], s.VerificationTag) + if opts.ComputeChecksums { + // Note: MakeTable(Castagnoli) actually only creates the table once, then + // passes back a singleton on every other call, so this shouldn't cause + // excessive memory allocation. + binary.LittleEndian.PutUint32(bytes[8:12], crc32.Checksum(b.Bytes(), crc32.MakeTable(crc32.Castagnoli))) + } + return nil +} + +func (sctp *SCTP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 12 { + return errors.New("Invalid SCTP common header length") + } + sctp.SrcPort = SCTPPort(binary.BigEndian.Uint16(data[:2])) + sctp.sPort = data[:2] + sctp.DstPort = SCTPPort(binary.BigEndian.Uint16(data[2:4])) + sctp.dPort = data[2:4] + sctp.VerificationTag = binary.BigEndian.Uint32(data[4:8]) + sctp.Checksum = binary.BigEndian.Uint32(data[8:12]) + sctp.BaseLayer = BaseLayer{data[:12], data[12:]} + + return nil +} + +func (t *SCTP) CanDecode() gopacket.LayerClass { + return LayerTypeSCTP +} + +func (t *SCTP) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypePayload +} + +// SCTPChunk contains the common fields in all SCTP chunks. +type SCTPChunk struct { + BaseLayer + 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 +} + +func roundUpToNearest4(i int) int { + if i%4 == 0 { + return i + } + return i + 4 - (i % 4) +} + +func decodeSCTPChunk(data []byte) (SCTPChunk, error) { + length := binary.BigEndian.Uint16(data[2:4]) + if length < 4 { + return SCTPChunk{}, errors.New("invalid SCTP chunk length") + } + actual := roundUpToNearest4(int(length)) + ct := SCTPChunkType(data[0]) + + // For SCTP Data, use a separate layer for the payload + delta := 0 + if ct == SCTPChunkTypeData { + delta = int(actual) - int(length) + actual = 16 + } + + return SCTPChunk{ + Type: ct, + Flags: data[1], + Length: length, + ActualLength: actual, + BaseLayer: BaseLayer{data[:actual], data[actual : len(data)-delta]}, + }, nil +} + +// SCTPParameter is a TLV parameter inside a SCTPChunk. +type SCTPParameter struct { + Type uint16 + Length uint16 + ActualLength int + Value []byte +} + +func decodeSCTPParameter(data []byte) SCTPParameter { + length := binary.BigEndian.Uint16(data[2:4]) + return SCTPParameter{ + Type: binary.BigEndian.Uint16(data[0:2]), + Length: length, + Value: data[4:length], + ActualLength: roundUpToNearest4(int(length)), + } +} + +func (p SCTPParameter) Bytes() []byte { + length := 4 + len(p.Value) + data := make([]byte, roundUpToNearest4(length)) + binary.BigEndian.PutUint16(data[0:2], p.Type) + binary.BigEndian.PutUint16(data[2:4], uint16(length)) + copy(data[4:], p.Value) + return data +} + +// 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. This chunk is stored as an ErrorLayer in the packet. +type SCTPUnknownChunkType struct { + SCTPChunk + bytes []byte +} + +func decodeSCTPChunkTypeUnknown(data []byte, p gopacket.PacketBuilder) error { + chunk, err := decodeSCTPChunk(data) + if err != nil { + return err + } + sc := &SCTPUnknownChunkType{SCTPChunk: chunk} + sc.bytes = data[:sc.ActualLength] + p.AddLayer(sc) + p.SetErrorLayer(sc) + return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix)) +} + +// SerializeTo is for gopacket.SerializableLayer. +func (s SCTPUnknownChunkType) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + bytes, err := b.PrependBytes(s.ActualLength) + if err != nil { + return err + } + copy(bytes, s.bytes) + return nil +} + +// LayerType returns gopacket.LayerTypeSCTPUnknownChunkType. +func (s *SCTPUnknownChunkType) LayerType() gopacket.LayerType { return LayerTypeSCTPUnknownChunkType } + +// Payload returns all bytes in this header, including the decoded Type, Length, +// 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) +} + +// SCTPData is the SCTP Data chunk layer. +type SCTPData struct { + SCTPChunk + Unordered, BeginFragment, EndFragment bool + TSN uint32 + StreamId uint16 + StreamSequence uint16 + PayloadProtocol SCTPPayloadProtocol +} + +// LayerType returns gopacket.LayerTypeSCTPData. +func (s *SCTPData) LayerType() gopacket.LayerType { return LayerTypeSCTPData } + +// SCTPPayloadProtocol represents a payload protocol +type SCTPPayloadProtocol uint32 + +// SCTPPayloadProtocol constonts from http://www.iana.org/assignments/sctp-parameters/sctp-parameters.xhtml +const ( + SCTPProtocolReserved SCTPPayloadProtocol = 0 + SCTPPayloadUIA = 1 + SCTPPayloadM2UA = 2 + SCTPPayloadM3UA = 3 + SCTPPayloadSUA = 4 + SCTPPayloadM2PA = 5 + SCTPPayloadV5UA = 6 + SCTPPayloadH248 = 7 + SCTPPayloadBICC = 8 + SCTPPayloadTALI = 9 + SCTPPayloadDUA = 10 + SCTPPayloadASAP = 11 + SCTPPayloadENRP = 12 + SCTPPayloadH323 = 13 + SCTPPayloadQIPC = 14 + SCTPPayloadSIMCO = 15 + SCTPPayloadDDPSegment = 16 + SCTPPayloadDDPStream = 17 + SCTPPayloadS1AP = 18 +) + +func (p SCTPPayloadProtocol) String() string { + switch p { + case SCTPProtocolReserved: + return "Reserved" + case SCTPPayloadUIA: + return "UIA" + case SCTPPayloadM2UA: + return "M2UA" + case SCTPPayloadM3UA: + return "M3UA" + case SCTPPayloadSUA: + return "SUA" + case SCTPPayloadM2PA: + return "M2PA" + case SCTPPayloadV5UA: + return "V5UA" + case SCTPPayloadH248: + return "H.248" + case SCTPPayloadBICC: + return "BICC" + case SCTPPayloadTALI: + return "TALI" + case SCTPPayloadDUA: + return "DUA" + case SCTPPayloadASAP: + return "ASAP" + case SCTPPayloadENRP: + return "ENRP" + case SCTPPayloadH323: + return "H.323" + case SCTPPayloadQIPC: + return "QIPC" + case SCTPPayloadSIMCO: + return "SIMCO" + case SCTPPayloadDDPSegment: + return "DDPSegment" + case SCTPPayloadDDPStream: + return "DDPStream" + case SCTPPayloadS1AP: + return "S1AP" + } + return fmt.Sprintf("Unknown(%d)", p) +} + +func decodeSCTPData(data []byte, p gopacket.PacketBuilder) error { + chunk, err := decodeSCTPChunk(data) + if err != nil { + return err + } + sc := &SCTPData{ + SCTPChunk: chunk, + 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: SCTPPayloadProtocol(binary.BigEndian.Uint32(data[12:16])), + } + // Length is the length in bytes of the data, INCLUDING the 16-byte header. + p.AddLayer(sc) + return p.NextDecoder(gopacket.LayerTypePayload) +} + +// SerializeTo is for gopacket.SerializableLayer. +func (sc SCTPData) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + payload := b.Bytes() + // Pad the payload to a 32 bit boundary + if rem := len(payload) % 4; rem != 0 { + b.AppendBytes(4 - rem) + } + length := 16 + bytes, err := b.PrependBytes(length) + if err != nil { + return err + } + bytes[0] = uint8(sc.Type) + flags := uint8(0) + if sc.Unordered { + flags |= 0x4 + } + if sc.BeginFragment { + flags |= 0x2 + } + if sc.EndFragment { + flags |= 0x1 + } + bytes[1] = flags + binary.BigEndian.PutUint16(bytes[2:4], uint16(length+len(payload))) + binary.BigEndian.PutUint32(bytes[4:8], sc.TSN) + binary.BigEndian.PutUint16(bytes[8:10], sc.StreamId) + binary.BigEndian.PutUint16(bytes[10:12], sc.StreamSequence) + binary.BigEndian.PutUint32(bytes[12:16], uint32(sc.PayloadProtocol)) + return nil +} + +// 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 +// messages. +type SCTPInit struct { + SCTPChunk + InitiateTag uint32 + AdvertisedReceiverWindowCredit uint32 + OutboundStreams, InboundStreams uint16 + InitialTSN uint32 + Parameters []SCTPInitParameter +} + +// LayerType returns either gopacket.LayerTypeSCTPInit or gopacket.LayerTypeSCTPInitAck. +func (sc *SCTPInit) LayerType() gopacket.LayerType { + if sc.Type == SCTPChunkTypeInitAck { + return LayerTypeSCTPInitAck + } + // sc.Type == SCTPChunkTypeInit + return LayerTypeSCTPInit +} + +func decodeSCTPInit(data []byte, p gopacket.PacketBuilder) error { + chunk, err := decodeSCTPChunk(data) + if err != nil { + return err + } + sc := &SCTPInit{ + SCTPChunk: chunk, + 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)) +} + +// SerializeTo is for gopacket.SerializableLayer. +func (sc SCTPInit) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + var payload []byte + for _, param := range sc.Parameters { + payload = append(payload, SCTPParameter(param).Bytes()...) + } + length := 20 + len(payload) + bytes, err := b.PrependBytes(roundUpToNearest4(length)) + if err != nil { + return err + } + bytes[0] = uint8(sc.Type) + bytes[1] = sc.Flags + binary.BigEndian.PutUint16(bytes[2:4], uint16(length)) + binary.BigEndian.PutUint32(bytes[4:8], sc.InitiateTag) + binary.BigEndian.PutUint32(bytes[8:12], sc.AdvertisedReceiverWindowCredit) + binary.BigEndian.PutUint16(bytes[12:14], sc.OutboundStreams) + binary.BigEndian.PutUint16(bytes[14:16], sc.InboundStreams) + binary.BigEndian.PutUint32(bytes[16:20], sc.InitialTSN) + copy(bytes[20:], payload) + return nil +} + +// SCTPSack is the SCTP Selective ACK chunk layer. +type SCTPSack struct { + SCTPChunk + CumulativeTSNAck uint32 + AdvertisedReceiverWindowCredit uint32 + NumGapACKs, NumDuplicateTSNs uint16 + GapACKs []uint16 + DuplicateTSNs []uint32 +} + +// LayerType return LayerTypeSCTPSack +func (sc *SCTPSack) LayerType() gopacket.LayerType { + return LayerTypeSCTPSack +} + +func decodeSCTPSack(data []byte, p gopacket.PacketBuilder) error { + chunk, err := decodeSCTPChunk(data) + if err != nil { + return err + } + sc := &SCTPSack{ + SCTPChunk: chunk, + 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)) +} + +// SerializeTo is for gopacket.SerializableLayer. +func (sc SCTPSack) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + length := 16 + 2*len(sc.GapACKs) + 4*len(sc.DuplicateTSNs) + bytes, err := b.PrependBytes(roundUpToNearest4(length)) + if err != nil { + return err + } + bytes[0] = uint8(sc.Type) + bytes[1] = sc.Flags + binary.BigEndian.PutUint16(bytes[2:4], uint16(length)) + binary.BigEndian.PutUint32(bytes[4:8], sc.CumulativeTSNAck) + binary.BigEndian.PutUint32(bytes[8:12], sc.AdvertisedReceiverWindowCredit) + binary.BigEndian.PutUint16(bytes[12:14], uint16(len(sc.GapACKs))) + binary.BigEndian.PutUint16(bytes[14:16], uint16(len(sc.DuplicateTSNs))) + for i, v := range sc.GapACKs { + binary.BigEndian.PutUint16(bytes[16+i*2:], v) + } + offset := 16 + 2*len(sc.GapACKs) + for i, v := range sc.DuplicateTSNs { + binary.BigEndian.PutUint32(bytes[offset+i*4:], v) + } + return nil +} + +// SCTPHeartbeatParameter is the parameter type used by SCTP heartbeat and +// heartbeat ack layers. +type SCTPHeartbeatParameter SCTPParameter + +// SCTPHeartbeat is the SCTP heartbeat layer, also used for heatbeat ack. +type SCTPHeartbeat struct { + SCTPChunk + Parameters []SCTPHeartbeatParameter +} + +// LayerType returns gopacket.LayerTypeSCTPHeartbeat. +func (sc *SCTPHeartbeat) LayerType() gopacket.LayerType { + if sc.Type == SCTPChunkTypeHeartbeatAck { + return LayerTypeSCTPHeartbeatAck + } + // sc.Type == SCTPChunkTypeHeartbeat + return LayerTypeSCTPHeartbeat +} + +func decodeSCTPHeartbeat(data []byte, p gopacket.PacketBuilder) error { + chunk, err := decodeSCTPChunk(data) + if err != nil { + return err + } + sc := &SCTPHeartbeat{ + SCTPChunk: chunk, + } + 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)) +} + +// SerializeTo is for gopacket.SerializableLayer. +func (sc SCTPHeartbeat) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + var payload []byte + for _, param := range sc.Parameters { + payload = append(payload, SCTPParameter(param).Bytes()...) + } + length := 4 + len(payload) + + bytes, err := b.PrependBytes(roundUpToNearest4(length)) + if err != nil { + return err + } + bytes[0] = uint8(sc.Type) + bytes[1] = sc.Flags + binary.BigEndian.PutUint16(bytes[2:4], uint16(length)) + copy(bytes[4:], payload) + return nil +} + +// SCTPErrorParameter is the parameter type used by SCTP Abort and Error layers. +type SCTPErrorParameter SCTPParameter + +// SCTPError is the SCTP error layer, also used for SCTP aborts. +type SCTPError struct { + SCTPChunk + Parameters []SCTPErrorParameter +} + +// LayerType returns LayerTypeSCTPAbort or LayerTypeSCTPError. +func (sc *SCTPError) LayerType() gopacket.LayerType { + if sc.Type == SCTPChunkTypeAbort { + return LayerTypeSCTPAbort + } + // sc.Type == SCTPChunkTypeError + return LayerTypeSCTPError +} + +func decodeSCTPError(data []byte, p gopacket.PacketBuilder) error { + // remarkably similar to decodeSCTPHeartbeat ;) + chunk, err := decodeSCTPChunk(data) + if err != nil { + return err + } + sc := &SCTPError{ + SCTPChunk: chunk, + } + paramData := data[4:sc.Length] + for len(paramData) > 0 { + p := SCTPErrorParameter(decodeSCTPParameter(paramData)) + paramData = paramData[p.ActualLength:] + sc.Parameters = append(sc.Parameters, p) + } + p.AddLayer(sc) + return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix)) +} + +// SerializeTo is for gopacket.SerializableLayer. +func (sc SCTPError) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + var payload []byte + for _, param := range sc.Parameters { + payload = append(payload, SCTPParameter(param).Bytes()...) + } + length := 4 + len(payload) + + bytes, err := b.PrependBytes(roundUpToNearest4(length)) + if err != nil { + return err + } + bytes[0] = uint8(sc.Type) + bytes[1] = sc.Flags + binary.BigEndian.PutUint16(bytes[2:4], uint16(length)) + copy(bytes[4:], payload) + return nil +} + +// SCTPShutdown is the SCTP shutdown layer. +type SCTPShutdown struct { + SCTPChunk + CumulativeTSNAck uint32 +} + +// LayerType returns gopacket.LayerTypeSCTPShutdown. +func (sc *SCTPShutdown) LayerType() gopacket.LayerType { return LayerTypeSCTPShutdown } + +func decodeSCTPShutdown(data []byte, p gopacket.PacketBuilder) error { + chunk, err := decodeSCTPChunk(data) + if err != nil { + return err + } + sc := &SCTPShutdown{ + SCTPChunk: chunk, + CumulativeTSNAck: binary.BigEndian.Uint32(data[4:8]), + } + p.AddLayer(sc) + return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix)) +} + +// SerializeTo is for gopacket.SerializableLayer. +func (sc SCTPShutdown) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + bytes, err := b.PrependBytes(8) + if err != nil { + return err + } + bytes[0] = uint8(sc.Type) + bytes[1] = sc.Flags + binary.BigEndian.PutUint16(bytes[2:4], 8) + binary.BigEndian.PutUint32(bytes[4:8], sc.CumulativeTSNAck) + return nil +} + +// SCTPShutdownAck is the SCTP shutdown layer. +type SCTPShutdownAck struct { + SCTPChunk +} + +// LayerType returns gopacket.LayerTypeSCTPShutdownAck. +func (sc *SCTPShutdownAck) LayerType() gopacket.LayerType { return LayerTypeSCTPShutdownAck } + +func decodeSCTPShutdownAck(data []byte, p gopacket.PacketBuilder) error { + chunk, err := decodeSCTPChunk(data) + if err != nil { + return err + } + sc := &SCTPShutdownAck{ + SCTPChunk: chunk, + } + p.AddLayer(sc) + return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix)) +} + +// SerializeTo is for gopacket.SerializableLayer. +func (sc SCTPShutdownAck) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + bytes, err := b.PrependBytes(4) + if err != nil { + return err + } + bytes[0] = uint8(sc.Type) + bytes[1] = sc.Flags + binary.BigEndian.PutUint16(bytes[2:4], 4) + return nil +} + +// SCTPCookieEcho is the SCTP Cookie Echo layer. +type SCTPCookieEcho struct { + SCTPChunk + Cookie []byte +} + +// LayerType returns gopacket.LayerTypeSCTPCookieEcho. +func (sc *SCTPCookieEcho) LayerType() gopacket.LayerType { return LayerTypeSCTPCookieEcho } + +func decodeSCTPCookieEcho(data []byte, p gopacket.PacketBuilder) error { + chunk, err := decodeSCTPChunk(data) + if err != nil { + return err + } + sc := &SCTPCookieEcho{ + SCTPChunk: chunk, + } + sc.Cookie = data[4:sc.Length] + p.AddLayer(sc) + return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix)) +} + +// SerializeTo is for gopacket.SerializableLayer. +func (sc SCTPCookieEcho) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + length := 4 + len(sc.Cookie) + bytes, err := b.PrependBytes(roundUpToNearest4(length)) + if err != nil { + return err + } + bytes[0] = uint8(sc.Type) + bytes[1] = sc.Flags + binary.BigEndian.PutUint16(bytes[2:4], uint16(length)) + copy(bytes[4:], sc.Cookie) + return nil +} + +// This struct is used by all empty SCTP chunks (currently CookieAck and +// ShutdownComplete). +type SCTPEmptyLayer struct { + SCTPChunk +} + +// LayerType returns either gopacket.LayerTypeSCTPShutdownComplete or +// LayerTypeSCTPCookieAck. +func (sc *SCTPEmptyLayer) LayerType() gopacket.LayerType { + if sc.Type == SCTPChunkTypeShutdownComplete { + return LayerTypeSCTPShutdownComplete + } + // sc.Type == SCTPChunkTypeCookieAck + return LayerTypeSCTPCookieAck +} + +func decodeSCTPEmptyLayer(data []byte, p gopacket.PacketBuilder) error { + chunk, err := decodeSCTPChunk(data) + if err != nil { + return err + } + sc := &SCTPEmptyLayer{ + SCTPChunk: chunk, + } + p.AddLayer(sc) + return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix)) +} + +// SerializeTo is for gopacket.SerializableLayer. +func (sc SCTPEmptyLayer) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + bytes, err := b.PrependBytes(4) + if err != nil { + return err + } + bytes[0] = uint8(sc.Type) + bytes[1] = sc.Flags + binary.BigEndian.PutUint16(bytes[2:4], 4) + return nil +} diff --git a/vendor/github.com/google/gopacket/layers/sflow.go b/vendor/github.com/google/gopacket/layers/sflow.go new file mode 100644 index 0000000..55ce31e --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/sflow.go @@ -0,0 +1,2187 @@ +// Copyright 2014 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +/* +This layer decodes SFlow version 5 datagrams. + +The specification can be found here: http://sflow.org/sflow_version_5.txt + +Additional developer information about sflow can be found at: +http://sflow.org/developers/specifications.php + +And SFlow in general: +http://sflow.org/index.php + +Two forms of sample data are defined: compact and expanded. The +Specification has this to say: + + Compact and expand forms of counter and flow samples are defined. + An agent must not mix compact/expanded encodings. If an agent + will never use ifIndex numbers >= 2^24 then it must use compact + encodings for all interfaces. Otherwise the expanded formats must + be used for all interfaces. + +This decoder only supports the compact form, because that is the only +one for which data was avaialble. + +The datagram is composed of one or more samples of type flow or counter, +and each sample is composed of one or more records describing the sample. +A sample is a single instance of sampled inforamtion, and each record in +the sample gives additional / supplimentary information about the sample. + +The following sample record types are supported: + + Raw Packet Header + opaque = flow_data; enterprise = 0; format = 1 + + Extended Switch Data + opaque = flow_data; enterprise = 0; format = 1001 + + Extended Router Data + opaque = flow_data; enterprise = 0; format = 1002 + + Extended Gateway Data + opaque = flow_data; enterprise = 0; format = 1003 + + Extended User Data + opaque = flow_data; enterprise = 0; format = 1004 + + Extended URL Data + opaque = flow_data; enterprise = 0; format = 1005 + +The following types of counter records are supported: + + Generic Interface Counters - see RFC 2233 + opaque = counter_data; enterprise = 0; format = 1 + + Ethernet Interface Counters - see RFC 2358 + opaque = counter_data; enterprise = 0; format = 2 + +SFlow is encoded using XDR (RFC4506). There are a few places +where the standard 4-byte fields are partitioned into two +bitfields of different lengths. I'm not sure why the designers +chose to pack together two values like this in some places, and +in others they use the entire 4-byte value to store a number that +will never be more than a few bits. In any case, there are a couple +of types defined to handle the decoding of these bitfields, and +that's why they're there. */ + +package layers + +import ( + "encoding/binary" + "errors" + "fmt" + "net" + + "github.com/google/gopacket" +) + +// SFlowRecord holds both flow sample records and counter sample records. +// A Record is the structure that actually holds the sampled data +// and / or counters. +type SFlowRecord interface { +} + +// SFlowDataSource encodes a 2-bit SFlowSourceFormat in its most significant +// 2 bits, and an SFlowSourceValue in its least significant 30 bits. +// These types and values define the meaning of the inteface information +// presented in the sample metadata. +type SFlowDataSource int32 + +func (sdc SFlowDataSource) decode() (SFlowSourceFormat, SFlowSourceValue) { + leftField := sdc >> 30 + rightField := uint32(0x3FFFFFFF) & uint32(sdc) + return SFlowSourceFormat(leftField), SFlowSourceValue(rightField) +} + +type SFlowDataSourceExpanded struct { + SourceIDClass SFlowSourceFormat + SourceIDIndex SFlowSourceValue +} + +func (sdce SFlowDataSourceExpanded) decode() (SFlowSourceFormat, SFlowSourceValue) { + leftField := sdce.SourceIDClass >> 30 + rightField := uint32(0x3FFFFFFF) & uint32(sdce.SourceIDIndex) + return SFlowSourceFormat(leftField), SFlowSourceValue(rightField) +} + +type SFlowSourceFormat uint32 + +type SFlowSourceValue uint32 + +const ( + SFlowTypeSingleInterface SFlowSourceFormat = 0 + SFlowTypePacketDiscarded SFlowSourceFormat = 1 + SFlowTypeMultipleDestinations SFlowSourceFormat = 2 +) + +func (sdf SFlowSourceFormat) String() string { + switch sdf { + case SFlowTypeSingleInterface: + return "Single Interface" + case SFlowTypePacketDiscarded: + return "Packet Discarded" + case SFlowTypeMultipleDestinations: + return "Multiple Destinations" + default: + return "UNKNOWN" + } +} + +func decodeSFlow(data []byte, p gopacket.PacketBuilder) error { + s := &SFlowDatagram{} + err := s.DecodeFromBytes(data, p) + if err != nil { + return err + } + p.AddLayer(s) + p.SetApplicationLayer(s) + return nil +} + +// SFlowDatagram is the outermost container which holds some basic information +// about the reporting agent, and holds at least one sample record +type SFlowDatagram struct { + BaseLayer + + DatagramVersion uint32 + AgentAddress net.IP + SubAgentID uint32 + SequenceNumber uint32 + AgentUptime uint32 + SampleCount uint32 + FlowSamples []SFlowFlowSample + CounterSamples []SFlowCounterSample +} + +// An SFlow datagram's outer container has the following +// structure: + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int sFlow version (2|4|5) | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int IP version of the Agent (1=v4|2=v6) | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / Agent IP address (v4=4byte|v6=16byte) / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int sub agent id | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int datagram sequence number | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int switch uptime in ms | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int n samples in datagram | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / n samples / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +// SFlowDataFormat encodes the EnterpriseID in the most +// significant 12 bits, and the SampleType in the least significant +// 20 bits. +type SFlowDataFormat uint32 + +func (sdf SFlowDataFormat) decode() (SFlowEnterpriseID, SFlowSampleType) { + leftField := sdf >> 12 + rightField := uint32(0xFFF) & uint32(sdf) + return SFlowEnterpriseID(leftField), SFlowSampleType(rightField) +} + +// SFlowEnterpriseID is used to differentiate between the +// official SFlow standard, and other, vendor-specific +// types of flow data. (Similiar to SNMP's enterprise MIB +// OIDs) Only the office SFlow Enterprise ID is decoded +// here. +type SFlowEnterpriseID uint32 + +const ( + SFlowStandard SFlowEnterpriseID = 0 +) + +func (eid SFlowEnterpriseID) String() string { + switch eid { + case SFlowStandard: + return "Standard SFlow" + default: + return "" + } +} + +func (eid SFlowEnterpriseID) GetType() SFlowEnterpriseID { + return SFlowStandard +} + +// SFlowSampleType specifies the type of sample. Only flow samples +// and counter samples are supported +type SFlowSampleType uint32 + +const ( + SFlowTypeFlowSample SFlowSampleType = 1 + SFlowTypeCounterSample SFlowSampleType = 2 + SFlowTypeExpandedFlowSample SFlowSampleType = 3 + SFlowTypeExpandedCounterSample SFlowSampleType = 4 +) + +func (st SFlowSampleType) GetType() SFlowSampleType { + switch st { + case SFlowTypeFlowSample: + return SFlowTypeFlowSample + case SFlowTypeCounterSample: + return SFlowTypeCounterSample + case SFlowTypeExpandedFlowSample: + return SFlowTypeExpandedFlowSample + case SFlowTypeExpandedCounterSample: + return SFlowTypeExpandedCounterSample + default: + panic("Invalid Sample Type") + } +} + +func (st SFlowSampleType) String() string { + switch st { + case SFlowTypeFlowSample: + return "Flow Sample" + case SFlowTypeCounterSample: + return "Counter Sample" + case SFlowTypeExpandedFlowSample: + return "Expanded Flow Sample" + case SFlowTypeExpandedCounterSample: + return "Expanded Counter Sample" + default: + return "" + } +} + +func (s *SFlowDatagram) LayerType() gopacket.LayerType { return LayerTypeSFlow } + +func (d *SFlowDatagram) Payload() []byte { return nil } + +func (d *SFlowDatagram) CanDecode() gopacket.LayerClass { return LayerTypeSFlow } + +func (d *SFlowDatagram) NextLayerType() gopacket.LayerType { return gopacket.LayerTypePayload } + +// SFlowIPType determines what form the IP address being decoded will +// take. This is an XDR union type allowing for both IPv4 and IPv6 +type SFlowIPType uint32 + +const ( + SFlowIPv4 SFlowIPType = 1 + SFlowIPv6 SFlowIPType = 2 +) + +func (s SFlowIPType) String() string { + switch s { + case SFlowIPv4: + return "IPv4" + case SFlowIPv6: + return "IPv6" + default: + return "" + } +} + +func (s SFlowIPType) Length() int { + switch s { + case SFlowIPv4: + return 4 + case SFlowIPv6: + return 16 + default: + return 0 + } +} + +func (s *SFlowDatagram) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + var agentAddressType SFlowIPType + + data, s.DatagramVersion = data[4:], binary.BigEndian.Uint32(data[:4]) + data, agentAddressType = data[4:], SFlowIPType(binary.BigEndian.Uint32(data[:4])) + data, s.AgentAddress = data[agentAddressType.Length():], data[:agentAddressType.Length()] + data, s.SubAgentID = data[4:], binary.BigEndian.Uint32(data[:4]) + data, s.SequenceNumber = data[4:], binary.BigEndian.Uint32(data[:4]) + data, s.AgentUptime = data[4:], binary.BigEndian.Uint32(data[:4]) + data, s.SampleCount = data[4:], binary.BigEndian.Uint32(data[:4]) + + if s.SampleCount < 1 { + return fmt.Errorf("SFlow Datagram has invalid sample length: %d", s.SampleCount) + } + for i := uint32(0); i < s.SampleCount; i++ { + sdf := SFlowDataFormat(binary.BigEndian.Uint32(data[:4])) + _, sampleType := sdf.decode() + switch sampleType { + case SFlowTypeFlowSample: + if flowSample, err := decodeFlowSample(&data, false); err == nil { + s.FlowSamples = append(s.FlowSamples, flowSample) + } else { + return err + } + case SFlowTypeCounterSample: + if counterSample, err := decodeCounterSample(&data, false); err == nil { + s.CounterSamples = append(s.CounterSamples, counterSample) + } else { + return err + } + case SFlowTypeExpandedFlowSample: + if flowSample, err := decodeFlowSample(&data, true); err == nil { + s.FlowSamples = append(s.FlowSamples, flowSample) + } else { + return err + } + case SFlowTypeExpandedCounterSample: + if counterSample, err := decodeCounterSample(&data, true); err == nil { + s.CounterSamples = append(s.CounterSamples, counterSample) + } else { + return err + } + + default: + return fmt.Errorf("Unsupported SFlow sample type %d", sampleType) + } + } + return nil +} + +// SFlowFlowSample represents a sampled packet and contains +// one or more records describing the packet +type SFlowFlowSample struct { + EnterpriseID SFlowEnterpriseID + Format SFlowSampleType + SampleLength uint32 + SequenceNumber uint32 + SourceIDClass SFlowSourceFormat + SourceIDIndex SFlowSourceValue + SamplingRate uint32 + SamplePool uint32 + Dropped uint32 + InputInterfaceFormat uint32 + InputInterface uint32 + OutputInterfaceFormat uint32 + OutputInterface uint32 + RecordCount uint32 + Records []SFlowRecord +} + +// Flow samples have the following structure. Note +// the bit fields to encode the Enterprise ID and the +// Flow record format: type 1 + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | sample length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int sample sequence number | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// |id type | src id index value | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int sampling rate | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int sample pool | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int drops | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int input ifIndex | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int output ifIndex | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int number of records | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / flow records / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +// Flow samples have the following structure. +// Flow record format: type 3 + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | sample length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int sample sequence number | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int src id type | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int src id index value | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int sampling rate | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int sample pool | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int drops | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int input interface format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int input interface value | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int output interface format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int output interface value | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int number of records | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / flow records / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +type SFlowFlowDataFormat uint32 + +func (fdf SFlowFlowDataFormat) decode() (SFlowEnterpriseID, SFlowFlowRecordType) { + leftField := fdf >> 12 + rightField := uint32(0xFFF) & uint32(fdf) + return SFlowEnterpriseID(leftField), SFlowFlowRecordType(rightField) +} + +func (fs SFlowFlowSample) GetRecords() []SFlowRecord { + return fs.Records +} + +func (fs SFlowFlowSample) GetType() SFlowSampleType { + return SFlowTypeFlowSample +} + +func skipRecord(data *[]byte) { + recordLength := int(binary.BigEndian.Uint32((*data)[4:])) + *data = (*data)[(recordLength+((4-recordLength)%4))+8:] +} + +func decodeFlowSample(data *[]byte, expanded bool) (SFlowFlowSample, error) { + s := SFlowFlowSample{} + var sdf SFlowDataFormat + *data, sdf = (*data)[4:], SFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + var sdc SFlowDataSource + + s.EnterpriseID, s.Format = sdf.decode() + *data, s.SampleLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, s.SequenceNumber = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + if expanded { + *data, s.SourceIDClass = (*data)[4:], SFlowSourceFormat(binary.BigEndian.Uint32((*data)[:4])) + *data, s.SourceIDIndex = (*data)[4:], SFlowSourceValue(binary.BigEndian.Uint32((*data)[:4])) + } else { + *data, sdc = (*data)[4:], SFlowDataSource(binary.BigEndian.Uint32((*data)[:4])) + s.SourceIDClass, s.SourceIDIndex = sdc.decode() + } + *data, s.SamplingRate = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, s.SamplePool = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, s.Dropped = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + + if expanded { + *data, s.InputInterfaceFormat = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, s.InputInterface = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, s.OutputInterfaceFormat = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, s.OutputInterface = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + } else { + *data, s.InputInterface = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, s.OutputInterface = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + } + *data, s.RecordCount = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + + for i := uint32(0); i < s.RecordCount; i++ { + rdf := SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + _, flowRecordType := rdf.decode() + + switch flowRecordType { + case SFlowTypeRawPacketFlow: + if record, err := decodeRawPacketFlowRecord(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedUserFlow: + if record, err := decodeExtendedUserFlow(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedUrlFlow: + if record, err := decodeExtendedURLRecord(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedSwitchFlow: + if record, err := decodeExtendedSwitchFlowRecord(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedRouterFlow: + if record, err := decodeExtendedRouterFlowRecord(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedGatewayFlow: + if record, err := decodeExtendedGatewayFlowRecord(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeEthernetFrameFlow: + // TODO + skipRecord(data) + return s, errors.New("skipping TypeEthernetFrameFlow") + case SFlowTypeIpv4Flow: + if record, err := decodeSFlowIpv4Record(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeIpv6Flow: + if record, err := decodeSFlowIpv6Record(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedMlpsFlow: + // TODO + skipRecord(data) + return s, errors.New("skipping TypeExtendedMlpsFlow") + case SFlowTypeExtendedNatFlow: + // TODO + skipRecord(data) + return s, errors.New("skipping TypeExtendedNatFlow") + case SFlowTypeExtendedMlpsTunnelFlow: + // TODO + skipRecord(data) + return s, errors.New("skipping TypeExtendedMlpsTunnelFlow") + case SFlowTypeExtendedMlpsVcFlow: + // TODO + skipRecord(data) + return s, errors.New("skipping TypeExtendedMlpsVcFlow") + case SFlowTypeExtendedMlpsFecFlow: + // TODO + skipRecord(data) + return s, errors.New("skipping TypeExtendedMlpsFecFlow") + case SFlowTypeExtendedMlpsLvpFecFlow: + // TODO + skipRecord(data) + return s, errors.New("skipping TypeExtendedMlpsLvpFecFlow") + case SFlowTypeExtendedVlanFlow: + // TODO + skipRecord(data) + return s, errors.New("skipping TypeExtendedVlanFlow") + case SFlowTypeExtendedIpv4TunnelEgressFlow: + if record, err := decodeExtendedIpv4TunnelEgress(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedIpv4TunnelIngressFlow: + if record, err := decodeExtendedIpv4TunnelIngress(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedIpv6TunnelEgressFlow: + if record, err := decodeExtendedIpv6TunnelEgress(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedIpv6TunnelIngressFlow: + if record, err := decodeExtendedIpv6TunnelIngress(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedDecapsulateEgressFlow: + if record, err := decodeExtendedDecapsulateEgress(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedDecapsulateIngressFlow: + if record, err := decodeExtendedDecapsulateIngress(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedVniEgressFlow: + if record, err := decodeExtendedVniEgress(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedVniIngressFlow: + if record, err := decodeExtendedVniIngress(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + default: + return s, fmt.Errorf("Unsupported flow record type: %d", flowRecordType) + } + } + return s, nil +} + +// Counter samples report information about various counter +// objects. Typically these are items like IfInOctets, or +// CPU / Memory stats, etc. SFlow will report these at regular +// intervals as configured on the agent. If one were sufficiently +// industrious, this could be used to replace the typical +// SNMP polling used for such things. +type SFlowCounterSample struct { + EnterpriseID SFlowEnterpriseID + Format SFlowSampleType + SampleLength uint32 + SequenceNumber uint32 + SourceIDClass SFlowSourceFormat + SourceIDIndex SFlowSourceValue + RecordCount uint32 + Records []SFlowRecord +} + +// Counter samples have the following structure: + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int sample sequence number | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// |id type | src id index value | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int number of records | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / counter records / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +type SFlowCounterDataFormat uint32 + +func (cdf SFlowCounterDataFormat) decode() (SFlowEnterpriseID, SFlowCounterRecordType) { + leftField := cdf >> 12 + rightField := uint32(0xFFF) & uint32(cdf) + return SFlowEnterpriseID(leftField), SFlowCounterRecordType(rightField) +} + +// GetRecords will return a slice of interface types +// representing records. A type switch can be used to +// get at the underlying SFlowCounterRecordType. +func (cs SFlowCounterSample) GetRecords() []SFlowRecord { + return cs.Records +} + +// GetType will report the type of sample. Only the +// compact form of counter samples is supported +func (cs SFlowCounterSample) GetType() SFlowSampleType { + return SFlowTypeCounterSample +} + +type SFlowCounterRecordType uint32 + +const ( + SFlowTypeGenericInterfaceCounters SFlowCounterRecordType = 1 + SFlowTypeEthernetInterfaceCounters SFlowCounterRecordType = 2 + SFlowTypeTokenRingInterfaceCounters SFlowCounterRecordType = 3 + SFlowType100BaseVGInterfaceCounters SFlowCounterRecordType = 4 + SFlowTypeVLANCounters SFlowCounterRecordType = 5 + SFlowTypeProcessorCounters SFlowCounterRecordType = 1001 +) + +func (cr SFlowCounterRecordType) String() string { + switch cr { + case SFlowTypeGenericInterfaceCounters: + return "Generic Interface Counters" + case SFlowTypeEthernetInterfaceCounters: + return "Ethernet Interface Counters" + case SFlowTypeTokenRingInterfaceCounters: + return "Token Ring Interface Counters" + case SFlowType100BaseVGInterfaceCounters: + return "100BaseVG Interface Counters" + case SFlowTypeVLANCounters: + return "VLAN Counters" + case SFlowTypeProcessorCounters: + return "Processor Counters" + default: + return "" + + } +} + +func decodeCounterSample(data *[]byte, expanded bool) (SFlowCounterSample, error) { + s := SFlowCounterSample{} + var sdc SFlowDataSource + var sdce SFlowDataSourceExpanded + var sdf SFlowDataFormat + + *data, sdf = (*data)[4:], SFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + s.EnterpriseID, s.Format = sdf.decode() + *data, s.SampleLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, s.SequenceNumber = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + if expanded { + *data, sdce = (*data)[8:], SFlowDataSourceExpanded{SFlowSourceFormat(binary.BigEndian.Uint32((*data)[:4])), SFlowSourceValue(binary.BigEndian.Uint32((*data)[4:8]))} + s.SourceIDClass, s.SourceIDIndex = sdce.decode() + } else { + *data, sdc = (*data)[4:], SFlowDataSource(binary.BigEndian.Uint32((*data)[:4])) + s.SourceIDClass, s.SourceIDIndex = sdc.decode() + } + *data, s.RecordCount = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + + for i := uint32(0); i < s.RecordCount; i++ { + cdf := SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4])) + _, counterRecordType := cdf.decode() + switch counterRecordType { + case SFlowTypeGenericInterfaceCounters: + if record, err := decodeGenericInterfaceCounters(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeEthernetInterfaceCounters: + if record, err := decodeEthernetCounters(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeTokenRingInterfaceCounters: + skipRecord(data) + return s, errors.New("skipping TypeTokenRingInterfaceCounters") + case SFlowType100BaseVGInterfaceCounters: + skipRecord(data) + return s, errors.New("skipping Type100BaseVGInterfaceCounters") + case SFlowTypeVLANCounters: + skipRecord(data) + return s, errors.New("skipping TypeVLANCounters") + case SFlowTypeProcessorCounters: + if record, err := decodeProcessorCounters(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + default: + return s, fmt.Errorf("Invalid counter record type: %d", counterRecordType) + } + } + return s, nil +} + +// SFlowBaseFlowRecord holds the fields common to all records +// of type SFlowFlowRecordType +type SFlowBaseFlowRecord struct { + EnterpriseID SFlowEnterpriseID + Format SFlowFlowRecordType + FlowDataLength uint32 +} + +func (bfr SFlowBaseFlowRecord) GetType() SFlowFlowRecordType { + return bfr.Format +} + +// SFlowFlowRecordType denotes what kind of Flow Record is +// represented. See RFC 3176 +type SFlowFlowRecordType uint32 + +const ( + SFlowTypeRawPacketFlow SFlowFlowRecordType = 1 + SFlowTypeEthernetFrameFlow SFlowFlowRecordType = 2 + SFlowTypeIpv4Flow SFlowFlowRecordType = 3 + SFlowTypeIpv6Flow SFlowFlowRecordType = 4 + SFlowTypeExtendedSwitchFlow SFlowFlowRecordType = 1001 + SFlowTypeExtendedRouterFlow SFlowFlowRecordType = 1002 + SFlowTypeExtendedGatewayFlow SFlowFlowRecordType = 1003 + SFlowTypeExtendedUserFlow SFlowFlowRecordType = 1004 + SFlowTypeExtendedUrlFlow SFlowFlowRecordType = 1005 + SFlowTypeExtendedMlpsFlow SFlowFlowRecordType = 1006 + SFlowTypeExtendedNatFlow SFlowFlowRecordType = 1007 + SFlowTypeExtendedMlpsTunnelFlow SFlowFlowRecordType = 1008 + SFlowTypeExtendedMlpsVcFlow SFlowFlowRecordType = 1009 + SFlowTypeExtendedMlpsFecFlow SFlowFlowRecordType = 1010 + SFlowTypeExtendedMlpsLvpFecFlow SFlowFlowRecordType = 1011 + SFlowTypeExtendedVlanFlow SFlowFlowRecordType = 1012 + SFlowTypeExtendedIpv4TunnelEgressFlow SFlowFlowRecordType = 1023 + SFlowTypeExtendedIpv4TunnelIngressFlow SFlowFlowRecordType = 1024 + SFlowTypeExtendedIpv6TunnelEgressFlow SFlowFlowRecordType = 1025 + SFlowTypeExtendedIpv6TunnelIngressFlow SFlowFlowRecordType = 1026 + SFlowTypeExtendedDecapsulateEgressFlow SFlowFlowRecordType = 1027 + SFlowTypeExtendedDecapsulateIngressFlow SFlowFlowRecordType = 1028 + SFlowTypeExtendedVniEgressFlow SFlowFlowRecordType = 1029 + SFlowTypeExtendedVniIngressFlow SFlowFlowRecordType = 1030 +) + +func (rt SFlowFlowRecordType) String() string { + switch rt { + case SFlowTypeRawPacketFlow: + return "Raw Packet Flow Record" + case SFlowTypeEthernetFrameFlow: + return "Ethernet Frame Flow Record" + case SFlowTypeIpv4Flow: + return "IPv4 Flow Record" + case SFlowTypeIpv6Flow: + return "IPv6 Flow Record" + case SFlowTypeExtendedSwitchFlow: + return "Extended Switch Flow Record" + case SFlowTypeExtendedRouterFlow: + return "Extended Router Flow Record" + case SFlowTypeExtendedGatewayFlow: + return "Extended Gateway Flow Record" + case SFlowTypeExtendedUserFlow: + return "Extended User Flow Record" + case SFlowTypeExtendedUrlFlow: + return "Extended URL Flow Record" + case SFlowTypeExtendedMlpsFlow: + return "Extended MPLS Flow Record" + case SFlowTypeExtendedNatFlow: + return "Extended NAT Flow Record" + case SFlowTypeExtendedMlpsTunnelFlow: + return "Extended MPLS Tunnel Flow Record" + case SFlowTypeExtendedMlpsVcFlow: + return "Extended MPLS VC Flow Record" + case SFlowTypeExtendedMlpsFecFlow: + return "Extended MPLS FEC Flow Record" + case SFlowTypeExtendedMlpsLvpFecFlow: + return "Extended MPLS LVP FEC Flow Record" + case SFlowTypeExtendedVlanFlow: + return "Extended VLAN Flow Record" + case SFlowTypeExtendedIpv4TunnelEgressFlow: + return "Extended IPv4 Tunnel Egress Record" + case SFlowTypeExtendedIpv4TunnelIngressFlow: + return "Extended IPv4 Tunnel Ingress Record" + case SFlowTypeExtendedIpv6TunnelEgressFlow: + return "Extended IPv6 Tunnel Egress Record" + case SFlowTypeExtendedIpv6TunnelIngressFlow: + return "Extended IPv6 Tunnel Ingress Record" + case SFlowTypeExtendedDecapsulateEgressFlow: + return "Extended Decapsulate Egress Record" + case SFlowTypeExtendedDecapsulateIngressFlow: + return "Extended Decapsulate Ingress Record" + case SFlowTypeExtendedVniEgressFlow: + return "Extended VNI Ingress Record" + case SFlowTypeExtendedVniIngressFlow: + return "Extended VNI Ingress Record" + default: + return "" + } +} + +// SFlowRawPacketFlowRecords hold information about a sampled +// packet grabbed as it transited the agent. This is +// perhaps the most useful and interesting record type, +// as it holds the headers of the sampled packet and +// can be used to build up a complete picture of the +// traffic patterns on a network. +// +// The raw packet header is sent back into gopacket for +// decoding, and the resulting gopackt.Packet is stored +// in the Header member +type SFlowRawPacketFlowRecord struct { + SFlowBaseFlowRecord + HeaderProtocol SFlowRawHeaderProtocol + FrameLength uint32 + PayloadRemoved uint32 + HeaderLength uint32 + Header gopacket.Packet +} + +// Raw packet record types have the following structure: + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | record length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Header Protocol | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Frame Length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Payload Removed | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Header Length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// \ Header \ +// \ \ +// \ \ +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +type SFlowRawHeaderProtocol uint32 + +const ( + SFlowProtoEthernet SFlowRawHeaderProtocol = 1 + SFlowProtoISO88024 SFlowRawHeaderProtocol = 2 + SFlowProtoISO88025 SFlowRawHeaderProtocol = 3 + SFlowProtoFDDI SFlowRawHeaderProtocol = 4 + SFlowProtoFrameRelay SFlowRawHeaderProtocol = 5 + SFlowProtoX25 SFlowRawHeaderProtocol = 6 + SFlowProtoPPP SFlowRawHeaderProtocol = 7 + SFlowProtoSMDS SFlowRawHeaderProtocol = 8 + SFlowProtoAAL5 SFlowRawHeaderProtocol = 9 + SFlowProtoAAL5_IP SFlowRawHeaderProtocol = 10 /* e.g. Cisco AAL5 mux */ + SFlowProtoIPv4 SFlowRawHeaderProtocol = 11 + SFlowProtoIPv6 SFlowRawHeaderProtocol = 12 + SFlowProtoMPLS SFlowRawHeaderProtocol = 13 + SFlowProtoPOS SFlowRawHeaderProtocol = 14 /* RFC 1662, 2615 */ +) + +func (sfhp SFlowRawHeaderProtocol) String() string { + switch sfhp { + case SFlowProtoEthernet: + return "ETHERNET-ISO88023" + case SFlowProtoISO88024: + return "ISO88024-TOKENBUS" + case SFlowProtoISO88025: + return "ISO88025-TOKENRING" + case SFlowProtoFDDI: + return "FDDI" + case SFlowProtoFrameRelay: + return "FRAME-RELAY" + case SFlowProtoX25: + return "X25" + case SFlowProtoPPP: + return "PPP" + case SFlowProtoSMDS: + return "SMDS" + case SFlowProtoAAL5: + return "AAL5" + case SFlowProtoAAL5_IP: + return "AAL5-IP" + case SFlowProtoIPv4: + return "IPv4" + case SFlowProtoIPv6: + return "IPv6" + case SFlowProtoMPLS: + return "MPLS" + case SFlowProtoPOS: + return "POS" + } + return "UNKNOWN" +} + +func decodeRawPacketFlowRecord(data *[]byte) (SFlowRawPacketFlowRecord, error) { + rec := SFlowRawPacketFlowRecord{} + header := []byte{} + var fdf SFlowFlowDataFormat + + *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + rec.EnterpriseID, rec.Format = fdf.decode() + *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, rec.HeaderProtocol = (*data)[4:], SFlowRawHeaderProtocol(binary.BigEndian.Uint32((*data)[:4])) + *data, rec.FrameLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, rec.PayloadRemoved = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, rec.HeaderLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + headerLenWithPadding := int(rec.HeaderLength + ((4 - rec.HeaderLength) % 4)) + *data, header = (*data)[headerLenWithPadding:], (*data)[:headerLenWithPadding] + rec.Header = gopacket.NewPacket(header, LayerTypeEthernet, gopacket.Default) + return rec, nil +} + +// SFlowExtendedSwitchFlowRecord give additional information +// about the sampled packet if it's available. It's mainly +// useful for getting at the incoming and outgoing VLANs +// An agent may or may not provide this information. +type SFlowExtendedSwitchFlowRecord struct { + SFlowBaseFlowRecord + IncomingVLAN uint32 + IncomingVLANPriority uint32 + OutgoingVLAN uint32 + OutgoingVLANPriority uint32 +} + +// Extended switch records have the following structure: + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | record length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Incoming VLAN | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Incoming VLAN Priority | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Outgoing VLAN | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Outgoing VLAN Priority | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +func decodeExtendedSwitchFlowRecord(data *[]byte) (SFlowExtendedSwitchFlowRecord, error) { + es := SFlowExtendedSwitchFlowRecord{} + var fdf SFlowFlowDataFormat + + *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + es.EnterpriseID, es.Format = fdf.decode() + *data, es.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, es.IncomingVLAN = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, es.IncomingVLANPriority = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, es.OutgoingVLAN = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, es.OutgoingVLANPriority = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + return es, nil +} + +// SFlowExtendedRouterFlowRecord gives additional information +// about the layer 3 routing information used to forward +// the packet +type SFlowExtendedRouterFlowRecord struct { + SFlowBaseFlowRecord + NextHop net.IP + NextHopSourceMask uint32 + NextHopDestinationMask uint32 +} + +// Extended router records have the following structure: + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | record length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IP version of next hop router (1=v4|2=v6) | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / Next Hop address (v4=4byte|v6=16byte) / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Next Hop Source Mask | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Next Hop Destination Mask | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +func decodeExtendedRouterFlowRecord(data *[]byte) (SFlowExtendedRouterFlowRecord, error) { + er := SFlowExtendedRouterFlowRecord{} + var fdf SFlowFlowDataFormat + var extendedRouterAddressType SFlowIPType + + *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + er.EnterpriseID, er.Format = fdf.decode() + *data, er.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, extendedRouterAddressType = (*data)[4:], SFlowIPType(binary.BigEndian.Uint32((*data)[:4])) + *data, er.NextHop = (*data)[extendedRouterAddressType.Length():], (*data)[:extendedRouterAddressType.Length()] + *data, er.NextHopSourceMask = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, er.NextHopDestinationMask = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + return er, nil +} + +// SFlowExtendedGatewayFlowRecord describes information treasured by +// nework engineers everywhere: AS path information listing which +// BGP peer sent the packet, and various other BGP related info. +// This information is vital because it gives a picture of how much +// traffic is being sent from / received by various BGP peers. + +// Extended gateway records have the following structure: + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | record length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IP version of next hop router (1=v4|2=v6) | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / Next Hop address (v4=4byte|v6=16byte) / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | AS | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Source AS | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Peer AS | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | AS Path Count | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / AS Path / Sequence / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / Communities / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Local Pref | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +// AS Path / Sequence: + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | AS Source Type (Path=1 / Sequence=2) | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Path / Sequence length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / Path / Sequence Members / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +// Communities: + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | communitiy length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / communitiy Members / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +type SFlowExtendedGatewayFlowRecord struct { + SFlowBaseFlowRecord + NextHop net.IP + AS uint32 + SourceAS uint32 + PeerAS uint32 + ASPathCount uint32 + ASPath []SFlowASDestination + Communities []uint32 + LocalPref uint32 +} + +type SFlowASPathType uint32 + +const ( + SFlowASSet SFlowASPathType = 1 + SFlowASSequence SFlowASPathType = 2 +) + +func (apt SFlowASPathType) String() string { + switch apt { + case SFlowASSet: + return "AS Set" + case SFlowASSequence: + return "AS Sequence" + default: + return "" + } +} + +type SFlowASDestination struct { + Type SFlowASPathType + Count uint32 + Members []uint32 +} + +func (asd SFlowASDestination) String() string { + switch asd.Type { + case SFlowASSet: + return fmt.Sprint("AS Set:", asd.Members) + case SFlowASSequence: + return fmt.Sprint("AS Sequence:", asd.Members) + default: + return "" + } +} + +func (ad *SFlowASDestination) decodePath(data *[]byte) { + *data, ad.Type = (*data)[4:], SFlowASPathType(binary.BigEndian.Uint32((*data)[:4])) + *data, ad.Count = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + ad.Members = make([]uint32, ad.Count) + for i := uint32(0); i < ad.Count; i++ { + var member uint32 + *data, member = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + ad.Members[i] = member + } +} + +func decodeExtendedGatewayFlowRecord(data *[]byte) (SFlowExtendedGatewayFlowRecord, error) { + eg := SFlowExtendedGatewayFlowRecord{} + var fdf SFlowFlowDataFormat + var extendedGatewayAddressType SFlowIPType + var communitiesLength uint32 + var community uint32 + + *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + eg.EnterpriseID, eg.Format = fdf.decode() + *data, eg.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, extendedGatewayAddressType = (*data)[4:], SFlowIPType(binary.BigEndian.Uint32((*data)[:4])) + *data, eg.NextHop = (*data)[extendedGatewayAddressType.Length():], (*data)[:extendedGatewayAddressType.Length()] + *data, eg.AS = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, eg.SourceAS = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, eg.PeerAS = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, eg.ASPathCount = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + for i := uint32(0); i < eg.ASPathCount; i++ { + asPath := SFlowASDestination{} + asPath.decodePath(data) + eg.ASPath = append(eg.ASPath, asPath) + } + *data, communitiesLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + eg.Communities = make([]uint32, communitiesLength) + for j := uint32(0); j < communitiesLength; j++ { + *data, community = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + eg.Communities[j] = community + } + *data, eg.LocalPref = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + return eg, nil +} + +// ************************************************** +// Extended URL Flow Record +// ************************************************** + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | record length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | direction | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | URL | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Host | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +type SFlowURLDirection uint32 + +const ( + SFlowURLsrc SFlowURLDirection = 1 + SFlowURLdst SFlowURLDirection = 2 +) + +func (urld SFlowURLDirection) String() string { + switch urld { + case SFlowURLsrc: + return "Source address is the server" + case SFlowURLdst: + return "Destination address is the server" + default: + return "" + } +} + +type SFlowExtendedURLRecord struct { + SFlowBaseFlowRecord + Direction SFlowURLDirection + URL string + Host string +} + +func decodeExtendedURLRecord(data *[]byte) (SFlowExtendedURLRecord, error) { + eur := SFlowExtendedURLRecord{} + var fdf SFlowFlowDataFormat + var urlLen uint32 + var urlLenWithPad int + var hostLen uint32 + var hostLenWithPad int + var urlBytes []byte + var hostBytes []byte + + *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + eur.EnterpriseID, eur.Format = fdf.decode() + *data, eur.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, eur.Direction = (*data)[4:], SFlowURLDirection(binary.BigEndian.Uint32((*data)[:4])) + *data, urlLen = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + urlLenWithPad = int(urlLen + ((4 - urlLen) % 4)) + *data, urlBytes = (*data)[urlLenWithPad:], (*data)[:urlLenWithPad] + eur.URL = string(urlBytes[:urlLen]) + *data, hostLen = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + hostLenWithPad = int(hostLen + ((4 - hostLen) % 4)) + *data, hostBytes = (*data)[hostLenWithPad:], (*data)[:hostLenWithPad] + eur.Host = string(hostBytes[:hostLen]) + return eur, nil +} + +// ************************************************** +// Extended User Flow Record +// ************************************************** + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | record length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Source Character Set | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Source User Id | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Destination Character Set | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Destination User ID | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +type SFlowExtendedUserFlow struct { + SFlowBaseFlowRecord + SourceCharSet SFlowCharSet + SourceUserID string + DestinationCharSet SFlowCharSet + DestinationUserID string +} + +type SFlowCharSet uint32 + +const ( + SFlowCSunknown SFlowCharSet = 2 + SFlowCSASCII SFlowCharSet = 3 + SFlowCSISOLatin1 SFlowCharSet = 4 + SFlowCSISOLatin2 SFlowCharSet = 5 + SFlowCSISOLatin3 SFlowCharSet = 6 + SFlowCSISOLatin4 SFlowCharSet = 7 + SFlowCSISOLatinCyrillic SFlowCharSet = 8 + SFlowCSISOLatinArabic SFlowCharSet = 9 + SFlowCSISOLatinGreek SFlowCharSet = 10 + SFlowCSISOLatinHebrew SFlowCharSet = 11 + SFlowCSISOLatin5 SFlowCharSet = 12 + SFlowCSISOLatin6 SFlowCharSet = 13 + SFlowCSISOTextComm SFlowCharSet = 14 + SFlowCSHalfWidthKatakana SFlowCharSet = 15 + SFlowCSJISEncoding SFlowCharSet = 16 + SFlowCSShiftJIS SFlowCharSet = 17 + SFlowCSEUCPkdFmtJapanese SFlowCharSet = 18 + SFlowCSEUCFixWidJapanese SFlowCharSet = 19 + SFlowCSISO4UnitedKingdom SFlowCharSet = 20 + SFlowCSISO11SwedishForNames SFlowCharSet = 21 + SFlowCSISO15Italian SFlowCharSet = 22 + SFlowCSISO17Spanish SFlowCharSet = 23 + SFlowCSISO21German SFlowCharSet = 24 + SFlowCSISO60DanishNorwegian SFlowCharSet = 25 + SFlowCSISO69French SFlowCharSet = 26 + SFlowCSISO10646UTF1 SFlowCharSet = 27 + SFlowCSISO646basic1983 SFlowCharSet = 28 + SFlowCSINVARIANT SFlowCharSet = 29 + SFlowCSISO2IntlRefVersion SFlowCharSet = 30 + SFlowCSNATSSEFI SFlowCharSet = 31 + SFlowCSNATSSEFIADD SFlowCharSet = 32 + SFlowCSNATSDANO SFlowCharSet = 33 + SFlowCSNATSDANOADD SFlowCharSet = 34 + SFlowCSISO10Swedish SFlowCharSet = 35 + SFlowCSKSC56011987 SFlowCharSet = 36 + SFlowCSISO2022KR SFlowCharSet = 37 + SFlowCSEUCKR SFlowCharSet = 38 + SFlowCSISO2022JP SFlowCharSet = 39 + SFlowCSISO2022JP2 SFlowCharSet = 40 + SFlowCSISO13JISC6220jp SFlowCharSet = 41 + SFlowCSISO14JISC6220ro SFlowCharSet = 42 + SFlowCSISO16Portuguese SFlowCharSet = 43 + SFlowCSISO18Greek7Old SFlowCharSet = 44 + SFlowCSISO19LatinGreek SFlowCharSet = 45 + SFlowCSISO25French SFlowCharSet = 46 + SFlowCSISO27LatinGreek1 SFlowCharSet = 47 + SFlowCSISO5427Cyrillic SFlowCharSet = 48 + SFlowCSISO42JISC62261978 SFlowCharSet = 49 + SFlowCSISO47BSViewdata SFlowCharSet = 50 + SFlowCSISO49INIS SFlowCharSet = 51 + SFlowCSISO50INIS8 SFlowCharSet = 52 + SFlowCSISO51INISCyrillic SFlowCharSet = 53 + SFlowCSISO54271981 SFlowCharSet = 54 + SFlowCSISO5428Greek SFlowCharSet = 55 + SFlowCSISO57GB1988 SFlowCharSet = 56 + SFlowCSISO58GB231280 SFlowCharSet = 57 + SFlowCSISO61Norwegian2 SFlowCharSet = 58 + SFlowCSISO70VideotexSupp1 SFlowCharSet = 59 + SFlowCSISO84Portuguese2 SFlowCharSet = 60 + SFlowCSISO85Spanish2 SFlowCharSet = 61 + SFlowCSISO86Hungarian SFlowCharSet = 62 + SFlowCSISO87JISX0208 SFlowCharSet = 63 + SFlowCSISO88Greek7 SFlowCharSet = 64 + SFlowCSISO89ASMO449 SFlowCharSet = 65 + SFlowCSISO90 SFlowCharSet = 66 + SFlowCSISO91JISC62291984a SFlowCharSet = 67 + SFlowCSISO92JISC62991984b SFlowCharSet = 68 + SFlowCSISO93JIS62291984badd SFlowCharSet = 69 + SFlowCSISO94JIS62291984hand SFlowCharSet = 70 + SFlowCSISO95JIS62291984handadd SFlowCharSet = 71 + SFlowCSISO96JISC62291984kana SFlowCharSet = 72 + SFlowCSISO2033 SFlowCharSet = 73 + SFlowCSISO99NAPLPS SFlowCharSet = 74 + SFlowCSISO102T617bit SFlowCharSet = 75 + SFlowCSISO103T618bit SFlowCharSet = 76 + SFlowCSISO111ECMACyrillic SFlowCharSet = 77 + SFlowCSa71 SFlowCharSet = 78 + SFlowCSa72 SFlowCharSet = 79 + SFlowCSISO123CSAZ24341985gr SFlowCharSet = 80 + SFlowCSISO88596E SFlowCharSet = 81 + SFlowCSISO88596I SFlowCharSet = 82 + SFlowCSISO128T101G2 SFlowCharSet = 83 + SFlowCSISO88598E SFlowCharSet = 84 + SFlowCSISO88598I SFlowCharSet = 85 + SFlowCSISO139CSN369103 SFlowCharSet = 86 + SFlowCSISO141JUSIB1002 SFlowCharSet = 87 + SFlowCSISO143IECP271 SFlowCharSet = 88 + SFlowCSISO146Serbian SFlowCharSet = 89 + SFlowCSISO147Macedonian SFlowCharSet = 90 + SFlowCSISO150 SFlowCharSet = 91 + SFlowCSISO151Cuba SFlowCharSet = 92 + SFlowCSISO6937Add SFlowCharSet = 93 + SFlowCSISO153GOST1976874 SFlowCharSet = 94 + SFlowCSISO8859Supp SFlowCharSet = 95 + SFlowCSISO10367Box SFlowCharSet = 96 + SFlowCSISO158Lap SFlowCharSet = 97 + SFlowCSISO159JISX02121990 SFlowCharSet = 98 + SFlowCSISO646Danish SFlowCharSet = 99 + SFlowCSUSDK SFlowCharSet = 100 + SFlowCSDKUS SFlowCharSet = 101 + SFlowCSKSC5636 SFlowCharSet = 102 + SFlowCSUnicode11UTF7 SFlowCharSet = 103 + SFlowCSISO2022CN SFlowCharSet = 104 + SFlowCSISO2022CNEXT SFlowCharSet = 105 + SFlowCSUTF8 SFlowCharSet = 106 + SFlowCSISO885913 SFlowCharSet = 109 + SFlowCSISO885914 SFlowCharSet = 110 + SFlowCSISO885915 SFlowCharSet = 111 + SFlowCSISO885916 SFlowCharSet = 112 + SFlowCSGBK SFlowCharSet = 113 + SFlowCSGB18030 SFlowCharSet = 114 + SFlowCSOSDEBCDICDF0415 SFlowCharSet = 115 + SFlowCSOSDEBCDICDF03IRV SFlowCharSet = 116 + SFlowCSOSDEBCDICDF041 SFlowCharSet = 117 + SFlowCSISO115481 SFlowCharSet = 118 + SFlowCSKZ1048 SFlowCharSet = 119 + SFlowCSUnicode SFlowCharSet = 1000 + SFlowCSUCS4 SFlowCharSet = 1001 + SFlowCSUnicodeASCII SFlowCharSet = 1002 + SFlowCSUnicodeLatin1 SFlowCharSet = 1003 + SFlowCSUnicodeJapanese SFlowCharSet = 1004 + SFlowCSUnicodeIBM1261 SFlowCharSet = 1005 + SFlowCSUnicodeIBM1268 SFlowCharSet = 1006 + SFlowCSUnicodeIBM1276 SFlowCharSet = 1007 + SFlowCSUnicodeIBM1264 SFlowCharSet = 1008 + SFlowCSUnicodeIBM1265 SFlowCharSet = 1009 + SFlowCSUnicode11 SFlowCharSet = 1010 + SFlowCSSCSU SFlowCharSet = 1011 + SFlowCSUTF7 SFlowCharSet = 1012 + SFlowCSUTF16BE SFlowCharSet = 1013 + SFlowCSUTF16LE SFlowCharSet = 1014 + SFlowCSUTF16 SFlowCharSet = 1015 + SFlowCSCESU8 SFlowCharSet = 1016 + SFlowCSUTF32 SFlowCharSet = 1017 + SFlowCSUTF32BE SFlowCharSet = 1018 + SFlowCSUTF32LE SFlowCharSet = 1019 + SFlowCSBOCU1 SFlowCharSet = 1020 + SFlowCSWindows30Latin1 SFlowCharSet = 2000 + SFlowCSWindows31Latin1 SFlowCharSet = 2001 + SFlowCSWindows31Latin2 SFlowCharSet = 2002 + SFlowCSWindows31Latin5 SFlowCharSet = 2003 + SFlowCSHPRoman8 SFlowCharSet = 2004 + SFlowCSAdobeStandardEncoding SFlowCharSet = 2005 + SFlowCSVenturaUS SFlowCharSet = 2006 + SFlowCSVenturaInternational SFlowCharSet = 2007 + SFlowCSDECMCS SFlowCharSet = 2008 + SFlowCSPC850Multilingual SFlowCharSet = 2009 + SFlowCSPCp852 SFlowCharSet = 2010 + SFlowCSPC8CodePage437 SFlowCharSet = 2011 + SFlowCSPC8DanishNorwegian SFlowCharSet = 2012 + SFlowCSPC862LatinHebrew SFlowCharSet = 2013 + SFlowCSPC8Turkish SFlowCharSet = 2014 + SFlowCSIBMSymbols SFlowCharSet = 2015 + SFlowCSIBMThai SFlowCharSet = 2016 + SFlowCSHPLegal SFlowCharSet = 2017 + SFlowCSHPPiFont SFlowCharSet = 2018 + SFlowCSHPMath8 SFlowCharSet = 2019 + SFlowCSHPPSMath SFlowCharSet = 2020 + SFlowCSHPDesktop SFlowCharSet = 2021 + SFlowCSVenturaMath SFlowCharSet = 2022 + SFlowCSMicrosoftPublishing SFlowCharSet = 2023 + SFlowCSWindows31J SFlowCharSet = 2024 + SFlowCSGB2312 SFlowCharSet = 2025 + SFlowCSBig5 SFlowCharSet = 2026 + SFlowCSMacintosh SFlowCharSet = 2027 + SFlowCSIBM037 SFlowCharSet = 2028 + SFlowCSIBM038 SFlowCharSet = 2029 + SFlowCSIBM273 SFlowCharSet = 2030 + SFlowCSIBM274 SFlowCharSet = 2031 + SFlowCSIBM275 SFlowCharSet = 2032 + SFlowCSIBM277 SFlowCharSet = 2033 + SFlowCSIBM278 SFlowCharSet = 2034 + SFlowCSIBM280 SFlowCharSet = 2035 + SFlowCSIBM281 SFlowCharSet = 2036 + SFlowCSIBM284 SFlowCharSet = 2037 + SFlowCSIBM285 SFlowCharSet = 2038 + SFlowCSIBM290 SFlowCharSet = 2039 + SFlowCSIBM297 SFlowCharSet = 2040 + SFlowCSIBM420 SFlowCharSet = 2041 + SFlowCSIBM423 SFlowCharSet = 2042 + SFlowCSIBM424 SFlowCharSet = 2043 + SFlowCSIBM500 SFlowCharSet = 2044 + SFlowCSIBM851 SFlowCharSet = 2045 + SFlowCSIBM855 SFlowCharSet = 2046 + SFlowCSIBM857 SFlowCharSet = 2047 + SFlowCSIBM860 SFlowCharSet = 2048 + SFlowCSIBM861 SFlowCharSet = 2049 + SFlowCSIBM863 SFlowCharSet = 2050 + SFlowCSIBM864 SFlowCharSet = 2051 + SFlowCSIBM865 SFlowCharSet = 2052 + SFlowCSIBM868 SFlowCharSet = 2053 + SFlowCSIBM869 SFlowCharSet = 2054 + SFlowCSIBM870 SFlowCharSet = 2055 + SFlowCSIBM871 SFlowCharSet = 2056 + SFlowCSIBM880 SFlowCharSet = 2057 + SFlowCSIBM891 SFlowCharSet = 2058 + SFlowCSIBM903 SFlowCharSet = 2059 + SFlowCSIBBM904 SFlowCharSet = 2060 + SFlowCSIBM905 SFlowCharSet = 2061 + SFlowCSIBM918 SFlowCharSet = 2062 + SFlowCSIBM1026 SFlowCharSet = 2063 + SFlowCSIBMEBCDICATDE SFlowCharSet = 2064 + SFlowCSEBCDICATDEA SFlowCharSet = 2065 + SFlowCSEBCDICCAFR SFlowCharSet = 2066 + SFlowCSEBCDICDKNO SFlowCharSet = 2067 + SFlowCSEBCDICDKNOA SFlowCharSet = 2068 + SFlowCSEBCDICFISE SFlowCharSet = 2069 + SFlowCSEBCDICFISEA SFlowCharSet = 2070 + SFlowCSEBCDICFR SFlowCharSet = 2071 + SFlowCSEBCDICIT SFlowCharSet = 2072 + SFlowCSEBCDICPT SFlowCharSet = 2073 + SFlowCSEBCDICES SFlowCharSet = 2074 + SFlowCSEBCDICESA SFlowCharSet = 2075 + SFlowCSEBCDICESS SFlowCharSet = 2076 + SFlowCSEBCDICUK SFlowCharSet = 2077 + SFlowCSEBCDICUS SFlowCharSet = 2078 + SFlowCSUnknown8BiT SFlowCharSet = 2079 + SFlowCSMnemonic SFlowCharSet = 2080 + SFlowCSMnem SFlowCharSet = 2081 + SFlowCSVISCII SFlowCharSet = 2082 + SFlowCSVIQR SFlowCharSet = 2083 + SFlowCSKOI8R SFlowCharSet = 2084 + SFlowCSHZGB2312 SFlowCharSet = 2085 + SFlowCSIBM866 SFlowCharSet = 2086 + SFlowCSPC775Baltic SFlowCharSet = 2087 + SFlowCSKOI8U SFlowCharSet = 2088 + SFlowCSIBM00858 SFlowCharSet = 2089 + SFlowCSIBM00924 SFlowCharSet = 2090 + SFlowCSIBM01140 SFlowCharSet = 2091 + SFlowCSIBM01141 SFlowCharSet = 2092 + SFlowCSIBM01142 SFlowCharSet = 2093 + SFlowCSIBM01143 SFlowCharSet = 2094 + SFlowCSIBM01144 SFlowCharSet = 2095 + SFlowCSIBM01145 SFlowCharSet = 2096 + SFlowCSIBM01146 SFlowCharSet = 2097 + SFlowCSIBM01147 SFlowCharSet = 2098 + SFlowCSIBM01148 SFlowCharSet = 2099 + SFlowCSIBM01149 SFlowCharSet = 2100 + SFlowCSBig5HKSCS SFlowCharSet = 2101 + SFlowCSIBM1047 SFlowCharSet = 2102 + SFlowCSPTCP154 SFlowCharSet = 2103 + SFlowCSAmiga1251 SFlowCharSet = 2104 + SFlowCSKOI7switched SFlowCharSet = 2105 + SFlowCSBRF SFlowCharSet = 2106 + SFlowCSTSCII SFlowCharSet = 2107 + SFlowCSCP51932 SFlowCharSet = 2108 + SFlowCSWindows874 SFlowCharSet = 2109 + SFlowCSWindows1250 SFlowCharSet = 2250 + SFlowCSWindows1251 SFlowCharSet = 2251 + SFlowCSWindows1252 SFlowCharSet = 2252 + SFlowCSWindows1253 SFlowCharSet = 2253 + SFlowCSWindows1254 SFlowCharSet = 2254 + SFlowCSWindows1255 SFlowCharSet = 2255 + SFlowCSWindows1256 SFlowCharSet = 2256 + SFlowCSWindows1257 SFlowCharSet = 2257 + SFlowCSWindows1258 SFlowCharSet = 2258 + SFlowCSTIS620 SFlowCharSet = 2259 + SFlowCS50220 SFlowCharSet = 2260 + SFlowCSreserved SFlowCharSet = 3000 +) + +func decodeExtendedUserFlow(data *[]byte) (SFlowExtendedUserFlow, error) { + eu := SFlowExtendedUserFlow{} + var fdf SFlowFlowDataFormat + var srcUserLen uint32 + var srcUserLenWithPad int + var srcUserBytes []byte + var dstUserLen uint32 + var dstUserLenWithPad int + var dstUserBytes []byte + + *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + eu.EnterpriseID, eu.Format = fdf.decode() + *data, eu.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, eu.SourceCharSet = (*data)[4:], SFlowCharSet(binary.BigEndian.Uint32((*data)[:4])) + *data, srcUserLen = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + srcUserLenWithPad = int(srcUserLen + ((4 - srcUserLen) % 4)) + *data, srcUserBytes = (*data)[srcUserLenWithPad:], (*data)[:srcUserLenWithPad] + eu.SourceUserID = string(srcUserBytes[:srcUserLen]) + *data, eu.DestinationCharSet = (*data)[4:], SFlowCharSet(binary.BigEndian.Uint32((*data)[:4])) + *data, dstUserLen = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + dstUserLenWithPad = int(dstUserLen + ((4 - dstUserLen) % 4)) + *data, dstUserBytes = (*data)[dstUserLenWithPad:], (*data)[:dstUserLenWithPad] + eu.DestinationUserID = string(dstUserBytes[:dstUserLen]) + return eu, nil +} + +// ************************************************** +// Packet IP version 4 Record +// ************************************************** + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Protocol | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Source IPv4 | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Destination IPv4 | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Source Port | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Destionation Port | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | TCP Flags | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | TOS | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +type SFlowIpv4Record struct { + // The length of the IP packet excluding ower layer encapsulations + Length uint32 + // IP Protocol type (for example, TCP = 6, UDP = 17) + Protocol uint32 + // Source IP Address + IPSrc net.IP + // Destination IP Address + IPDst net.IP + // TCP/UDP source port number or equivalent + PortSrc uint32 + // TCP/UDP destination port number or equivalent + PortDst uint32 + // TCP flags + TCPFlags uint32 + // IP type of service + TOS uint32 +} + +func decodeSFlowIpv4Record(data *[]byte) (SFlowIpv4Record, error) { + si := SFlowIpv4Record{} + + *data, si.Length = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, si.Protocol = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, si.IPSrc = (*data)[4:], net.IP((*data)[:4]) + *data, si.IPDst = (*data)[4:], net.IP((*data)[:4]) + *data, si.PortSrc = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, si.PortDst = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, si.TCPFlags = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, si.TOS = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + + return si, nil +} + +// ************************************************** +// Packet IP version 6 Record +// ************************************************** + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Protocol | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Source IPv4 | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Destination IPv4 | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Source Port | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Destionation Port | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | TCP Flags | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Priority | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +type SFlowIpv6Record struct { + // The length of the IP packet excluding ower layer encapsulations + Length uint32 + // IP Protocol type (for example, TCP = 6, UDP = 17) + Protocol uint32 + // Source IP Address + IPSrc net.IP + // Destination IP Address + IPDst net.IP + // TCP/UDP source port number or equivalent + PortSrc uint32 + // TCP/UDP destination port number or equivalent + PortDst uint32 + // TCP flags + TCPFlags uint32 + // IP priority + Priority uint32 +} + +func decodeSFlowIpv6Record(data *[]byte) (SFlowIpv6Record, error) { + si := SFlowIpv6Record{} + + *data, si.Length = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, si.Protocol = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, si.IPSrc = (*data)[16:], net.IP((*data)[:16]) + *data, si.IPDst = (*data)[16:], net.IP((*data)[:16]) + *data, si.PortSrc = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, si.PortDst = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, si.TCPFlags = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, si.Priority = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + + return si, nil +} + +// ************************************************** +// Extended IPv4 Tunnel Egress +// ************************************************** + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | record length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / Packet IP version 4 Record / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +type SFlowExtendedIpv4TunnelEgressRecord struct { + SFlowBaseFlowRecord + SFlowIpv4Record SFlowIpv4Record +} + +func decodeExtendedIpv4TunnelEgress(data *[]byte) (SFlowExtendedIpv4TunnelEgressRecord, error) { + rec := SFlowExtendedIpv4TunnelEgressRecord{} + var fdf SFlowFlowDataFormat + + *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + rec.EnterpriseID, rec.Format = fdf.decode() + *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + rec.SFlowIpv4Record, _ = decodeSFlowIpv4Record(data) + + return rec, nil +} + +// ************************************************** +// Extended IPv4 Tunnel Ingress +// ************************************************** + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | record length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / Packet IP version 4 Record / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +type SFlowExtendedIpv4TunnelIngressRecord struct { + SFlowBaseFlowRecord + SFlowIpv4Record SFlowIpv4Record +} + +func decodeExtendedIpv4TunnelIngress(data *[]byte) (SFlowExtendedIpv4TunnelIngressRecord, error) { + rec := SFlowExtendedIpv4TunnelIngressRecord{} + var fdf SFlowFlowDataFormat + + *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + rec.EnterpriseID, rec.Format = fdf.decode() + *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + rec.SFlowIpv4Record, _ = decodeSFlowIpv4Record(data) + + return rec, nil +} + +// ************************************************** +// Extended IPv6 Tunnel Egress +// ************************************************** + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | record length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / Packet IP version 6 Record / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +type SFlowExtendedIpv6TunnelEgressRecord struct { + SFlowBaseFlowRecord + SFlowIpv6Record +} + +func decodeExtendedIpv6TunnelEgress(data *[]byte) (SFlowExtendedIpv6TunnelEgressRecord, error) { + rec := SFlowExtendedIpv6TunnelEgressRecord{} + var fdf SFlowFlowDataFormat + + *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + rec.EnterpriseID, rec.Format = fdf.decode() + *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + rec.SFlowIpv6Record, _ = decodeSFlowIpv6Record(data) + + return rec, nil +} + +// ************************************************** +// Extended IPv6 Tunnel Ingress +// ************************************************** + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | record length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / Packet IP version 6 Record / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +type SFlowExtendedIpv6TunnelIngressRecord struct { + SFlowBaseFlowRecord + SFlowIpv6Record +} + +func decodeExtendedIpv6TunnelIngress(data *[]byte) (SFlowExtendedIpv6TunnelIngressRecord, error) { + rec := SFlowExtendedIpv6TunnelIngressRecord{} + var fdf SFlowFlowDataFormat + + *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + rec.EnterpriseID, rec.Format = fdf.decode() + *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + rec.SFlowIpv6Record, _ = decodeSFlowIpv6Record(data) + + return rec, nil +} + +// ************************************************** +// Extended Decapsulate Egress +// ************************************************** + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | record length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Inner Header Offset | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +type SFlowExtendedDecapsulateEgressRecord struct { + SFlowBaseFlowRecord + InnerHeaderOffset uint32 +} + +func decodeExtendedDecapsulateEgress(data *[]byte) (SFlowExtendedDecapsulateEgressRecord, error) { + rec := SFlowExtendedDecapsulateEgressRecord{} + var fdf SFlowFlowDataFormat + + *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + rec.EnterpriseID, rec.Format = fdf.decode() + *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, rec.InnerHeaderOffset = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + + return rec, nil +} + +// ************************************************** +// Extended Decapsulate Ingress +// ************************************************** + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | record length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Inner Header Offset | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +type SFlowExtendedDecapsulateIngressRecord struct { + SFlowBaseFlowRecord + InnerHeaderOffset uint32 +} + +func decodeExtendedDecapsulateIngress(data *[]byte) (SFlowExtendedDecapsulateIngressRecord, error) { + rec := SFlowExtendedDecapsulateIngressRecord{} + var fdf SFlowFlowDataFormat + + *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + rec.EnterpriseID, rec.Format = fdf.decode() + *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, rec.InnerHeaderOffset = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + + return rec, nil +} + +// ************************************************** +// Extended VNI Egress +// ************************************************** + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | record length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | VNI | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +type SFlowExtendedVniEgressRecord struct { + SFlowBaseFlowRecord + VNI uint32 +} + +func decodeExtendedVniEgress(data *[]byte) (SFlowExtendedVniEgressRecord, error) { + rec := SFlowExtendedVniEgressRecord{} + var fdf SFlowFlowDataFormat + + *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + rec.EnterpriseID, rec.Format = fdf.decode() + *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, rec.VNI = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + + return rec, nil +} + +// ************************************************** +// Extended VNI Ingress +// ************************************************** + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | record length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | VNI | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +type SFlowExtendedVniIngressRecord struct { + SFlowBaseFlowRecord + VNI uint32 +} + +func decodeExtendedVniIngress(data *[]byte) (SFlowExtendedVniIngressRecord, error) { + rec := SFlowExtendedVniIngressRecord{} + var fdf SFlowFlowDataFormat + + *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + rec.EnterpriseID, rec.Format = fdf.decode() + *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, rec.VNI = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + + return rec, nil +} + +// ************************************************** +// Counter Record +// ************************************************** + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | counter length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / counter data / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +type SFlowBaseCounterRecord struct { + EnterpriseID SFlowEnterpriseID + Format SFlowCounterRecordType + FlowDataLength uint32 +} + +func (bcr SFlowBaseCounterRecord) GetType() SFlowCounterRecordType { + switch bcr.Format { + case SFlowTypeGenericInterfaceCounters: + return SFlowTypeGenericInterfaceCounters + case SFlowTypeEthernetInterfaceCounters: + return SFlowTypeEthernetInterfaceCounters + case SFlowTypeTokenRingInterfaceCounters: + return SFlowTypeTokenRingInterfaceCounters + case SFlowType100BaseVGInterfaceCounters: + return SFlowType100BaseVGInterfaceCounters + case SFlowTypeVLANCounters: + return SFlowTypeVLANCounters + case SFlowTypeProcessorCounters: + return SFlowTypeProcessorCounters + + } + unrecognized := fmt.Sprint("Unrecognized counter record type:", bcr.Format) + panic(unrecognized) +} + +// ************************************************** +// Counter Record +// ************************************************** + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | counter length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfIndex | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfType | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfSpeed | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfDirection | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfStatus | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IFInOctets | +// | | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfInUcastPkts | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfInMulticastPkts | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfInBroadcastPkts | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfInDiscards | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | InInErrors | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfInUnknownProtos | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfOutOctets | +// | | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfOutUcastPkts | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfOutMulticastPkts | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfOutBroadcastPkts | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfOutDiscards | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfOUtErrors | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfPromiscouousMode | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +type SFlowGenericInterfaceCounters struct { + SFlowBaseCounterRecord + IfIndex uint32 + IfType uint32 + IfSpeed uint64 + IfDirection uint32 + IfStatus uint32 + IfInOctets uint64 + IfInUcastPkts uint32 + IfInMulticastPkts uint32 + IfInBroadcastPkts uint32 + IfInDiscards uint32 + IfInErrors uint32 + IfInUnknownProtos uint32 + IfOutOctets uint64 + IfOutUcastPkts uint32 + IfOutMulticastPkts uint32 + IfOutBroadcastPkts uint32 + IfOutDiscards uint32 + IfOutErrors uint32 + IfPromiscuousMode uint32 +} + +func decodeGenericInterfaceCounters(data *[]byte) (SFlowGenericInterfaceCounters, error) { + gic := SFlowGenericInterfaceCounters{} + var cdf SFlowCounterDataFormat + + *data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4])) + gic.EnterpriseID, gic.Format = cdf.decode() + *data, gic.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfIndex = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfType = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfSpeed = (*data)[8:], binary.BigEndian.Uint64((*data)[:8]) + *data, gic.IfDirection = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfStatus = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfInOctets = (*data)[8:], binary.BigEndian.Uint64((*data)[:8]) + *data, gic.IfInUcastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfInMulticastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfInBroadcastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfInDiscards = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfInErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfInUnknownProtos = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfOutOctets = (*data)[8:], binary.BigEndian.Uint64((*data)[:8]) + *data, gic.IfOutUcastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfOutMulticastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfOutBroadcastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfOutDiscards = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfOutErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfPromiscuousMode = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + return gic, nil +} + +// ************************************************** +// Counter Record +// ************************************************** + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | counter length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / counter data / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +type SFlowEthernetCounters struct { + SFlowBaseCounterRecord + AlignmentErrors uint32 + FCSErrors uint32 + SingleCollisionFrames uint32 + MultipleCollisionFrames uint32 + SQETestErrors uint32 + DeferredTransmissions uint32 + LateCollisions uint32 + ExcessiveCollisions uint32 + InternalMacTransmitErrors uint32 + CarrierSenseErrors uint32 + FrameTooLongs uint32 + InternalMacReceiveErrors uint32 + SymbolErrors uint32 +} + +func decodeEthernetCounters(data *[]byte) (SFlowEthernetCounters, error) { + ec := SFlowEthernetCounters{} + var cdf SFlowCounterDataFormat + + *data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4])) + ec.EnterpriseID, ec.Format = cdf.decode() + *data, ec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ec.AlignmentErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ec.FCSErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ec.SingleCollisionFrames = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ec.MultipleCollisionFrames = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ec.SQETestErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ec.DeferredTransmissions = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ec.LateCollisions = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ec.ExcessiveCollisions = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ec.InternalMacTransmitErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ec.CarrierSenseErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ec.FrameTooLongs = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ec.InternalMacReceiveErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ec.SymbolErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + return ec, nil +} + +// ************************************************** +// Processor Counter Record +// ************************************************** +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | counter length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | FiveSecCpu | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | OneMinCpu | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | GiveMinCpu | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | TotalMemory | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | FreeMemory | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +type SFlowProcessorCounters struct { + SFlowBaseCounterRecord + FiveSecCpu uint32 // 5 second average CPU utilization + OneMinCpu uint32 // 1 minute average CPU utilization + FiveMinCpu uint32 // 5 minute average CPU utilization + TotalMemory uint64 // total memory (in bytes) + FreeMemory uint64 // free memory (in bytes) +} + +func decodeProcessorCounters(data *[]byte) (SFlowProcessorCounters, error) { + pc := SFlowProcessorCounters{} + var cdf SFlowCounterDataFormat + var high32, low32 uint32 + + *data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4])) + pc.EnterpriseID, pc.Format = cdf.decode() + *data, pc.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + + *data, pc.FiveSecCpu = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, pc.OneMinCpu = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, pc.FiveMinCpu = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, high32 = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, low32 = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + pc.TotalMemory = (uint64(high32) << 32) + uint64(low32) + *data, high32 = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, low32 = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + pc.FreeMemory = (uint64(high32)) + uint64(low32) + + return pc, nil +} diff --git a/vendor/github.com/google/gopacket/layers/sflow_test.go b/vendor/github.com/google/gopacket/layers/sflow_test.go new file mode 100644 index 0000000..ca0f2ab --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/sflow_test.go @@ -0,0 +1,1246 @@ +// Copyright 2014 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. +package layers + +import ( + "github.com/google/gopacket" + "net" + "reflect" + "testing" +) + +// Test packet collected from live network. See the test below for contents +var SFlowTestPacket1 = []byte{ + 0x84, 0x2b, 0x2b, 0x16, 0x8b, 0x62, 0xf0, 0x50, 0x56, 0x85, 0x3a, 0xfd, 0x08, 0x00, 0x45, 0x00, + 0x05, 0xbc, 0x9c, 0x04, 0x40, 0x00, 0xff, 0x11, 0xc7, 0x00, 0x0a, 0x01, 0xff, 0x0e, 0x0a, 0x01, + 0x00, 0x1b, 0xc7, 0x57, 0x18, 0xc7, 0x05, 0xa8, 0x22, 0x3b, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x01, 0x0a, 0x01, 0xf8, 0x16, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x9d, 0xfb, 0x40, 0x49, + 0xc6, 0xcd, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x26, + 0x27, 0xe8, 0x00, 0x00, 0x02, 0x13, 0x00, 0x00, 0x3e, 0x80, 0x50, 0xbd, 0xe5, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x05, 0xd2, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x3c, 0x8a, 0xb0, 0xe7, 0x54, 0x41, 0xb8, 0xca, 0x3a, 0x6d, + 0xf0, 0x40, 0x08, 0x00, 0x45, 0x00, 0x05, 0xc0, 0x6b, 0xaa, 0x40, 0x00, 0x40, 0x06, 0x8f, 0x41, + 0x0a, 0x01, 0x0e, 0x16, 0x36, 0xf0, 0xeb, 0x45, 0x76, 0xfd, 0x00, 0x50, 0xca, 0x77, 0xef, 0x96, + 0xfc, 0x28, 0x63, 0x40, 0x50, 0x10, 0x00, 0x3c, 0x64, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0xf4, 0x00, 0x00, 0x02, 0x77, 0x00, 0x00, 0x00, 0xfd, 0x3b, 0x8c, 0xe7, 0x04, 0x4a, 0x2d, 0xb2, + 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x01, 0x48, 0xcc, 0x11, 0x0d, 0xe3, 0x00, + 0x26, 0x85, 0x30, 0x00, 0x00, 0x07, 0x66, 0x00, 0x02, 0xd0, 0x8a, 0x00, 0x02, 0xce, 0xf0, 0x00, + 0x29, 0x7e, 0x80, 0x00, 0x02, 0xd0, 0x98, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x26, 0x85, 0x30, 0x00, + 0x00, 0x00, 0xf4, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03, 0xe9, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0xd0, 0x01, 0x5e, 0x5c, 0x1e, 0x00, 0x00, 0x02, 0x57, 0x00, 0x00, + 0x07, 0xd0, 0xb1, 0x2f, 0xa2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x57, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x05, 0xee, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x3c, 0x8a, + 0xb0, 0xe7, 0x54, 0x41, 0xb8, 0xca, 0x3a, 0x6f, 0xbe, 0xd8, 0x08, 0x00, 0x45, 0x00, 0x05, 0xdc, + 0x9f, 0xfd, 0x40, 0x00, 0x40, 0x06, 0x6a, 0xfa, 0x0a, 0x01, 0x0e, 0x10, 0x0a, 0x01, 0x08, 0x13, + 0x23, 0x84, 0xb7, 0x22, 0x8a, 0xc9, 0x50, 0xb5, 0x4e, 0x10, 0x2a, 0x87, 0x80, 0x10, 0x06, 0x01, + 0x10, 0xa6, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0xef, 0x1f, 0xf4, 0x07, 0x99, 0x3a, 0xd8, 0x5b, + 0x01, 0x46, 0x09, 0x00, 0x0c, 0x00, 0x0c, 0x3c, 0xac, 0x4a, 0x1b, 0x06, 0x04, 0x78, 0x78, 0x4e, + 0xc2, 0x05, 0x46, 0x43, 0x06, 0x04, 0x78, 0x78, 0xee, 0x9c, 0x00, 0x41, 0xef, 0x05, 0x81, 0x32, + 0x1b, 0x06, 0x04, 0x78, 0x78, 0x56, 0x72, 0x05, 0x4e, 0x92, 0x00, 0x96, 0x39, 0x00, 0xea, 0x3f, + 0x01, 0x15, 0xa3, 0x08, 0x04, 0x42, 0x6a, 0x82, 0x87, 0x08, 0x05, 0xcc, 0x00, 0x04, 0x00, 0x00, + 0x03, 0xe9, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xd0, 0x01, 0x5a, + 0xcd, 0xd0, 0x00, 0x00, 0x02, 0x55, 0x00, 0x00, 0x07, 0xd0, 0x95, 0x67, 0xe1, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x46, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x3c, 0x8a, 0xb0, 0xe7, 0x54, 0x41, 0xb8, 0xca, 0x3a, 0x6f, + 0x11, 0x28, 0x08, 0x00, 0x45, 0x00, 0x04, 0x34, 0xdb, 0x36, 0x40, 0x00, 0x40, 0x06, 0x38, 0xac, + 0x0a, 0x01, 0x0e, 0x11, 0x0a, 0x01, 0x00, 0xcf, 0x23, 0x84, 0xa0, 0x3f, 0x3c, 0xce, 0xd5, 0x4a, + 0x72, 0x0b, 0x5d, 0x1a, 0x80, 0x10, 0x06, 0x01, 0x8a, 0x50, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, + 0xef, 0x1f, 0xa2, 0xba, 0xe6, 0xfa, 0xae, 0xb3, 0xfe, 0xcf, 0x00, 0x19, 0xcf, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xb9, 0x79, 0xdd, 0x42, 0x00, 0x00, 0x02, 0x84, 0x9b, 0xa9, 0x02, 0xe2, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x32, 0x39, 0x35, 0x34, 0x33, 0x36, 0x00, 0x00, 0x02, 0x70, 0xcd, + 0x16, 0x40, 0xa6, 0x98, 0x88, 0x24, 0x06, 0x50, 0xb0, 0xf4, 0xee, 0x03, 0xa6, 0xfa, 0x87, 0xaf, + 0xc1, 0x99, 0x52, 0x0d, 0x07, 0xa8, 0x00, 0x00, 0x03, 0xe9, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x20, 0xf2, 0x00, 0x00, 0x02, 0x0a, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x02, 0x0a, 0x00, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x54, 0x0b, 0xe4, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x01, 0x29, 0x82, 0x6d, 0xb0, 0x6c, 0x0b, 0xcb, 0x0d, 0xdd, 0x96, 0x00, 0x06, + 0xa8, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x34, 0x02, 0x35, 0x58, 0x7c, 0x9e, 0x56, 0x64, 0x25, 0x71, 0x00, 0x70, + 0x5a, 0xc4, 0x00, 0x09, 0x08, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0xd0, 0x01, 0x5e, 0x5c, 0x1f, 0x00, 0x00, 0x02, 0x57, 0x00, 0x00, + 0x07, 0xd0, 0xb1, 0x2f, 0xaa, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x57, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x05, 0xee, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x3c, 0x8a, + 0xb0, 0xe7, 0x54, 0x41, 0xb8, 0xca, 0x3a, 0x6f, 0xbe, 0xd8, 0x08, 0x00, 0x45, 0x00, 0x05, 0xdc, + 0x0f, 0xba, 0x40, 0x00, 0x40, 0x06, 0xf4, 0x3f, 0x0a, 0x01, 0x0e, 0x10, 0x0a, 0x01, 0x0f, 0x11, + 0x23, 0x84, 0xcd, 0xc0, 0xf4, 0x0e, 0x90, 0x23, 0xd7, 0x32, 0x8b, 0x31, 0x80, 0x10, 0x00, 0x1d, + 0x6b, 0x12, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0xef, 0x1f, 0xf4, 0x28, 0xef, 0x1f, 0xec, 0x76, + 0xaa, 0x25, 0x01, 0x04, 0xc0, 0xac, 0xfe, 0x25, 0x01, 0x8e, 0x25, 0x01, 0x16, 0xc7, 0x28, 0xfe, + 0x7e, 0x70, 0xfe, 0x7e, 0x70, 0x52, 0x7e, 0x70, 0x15, 0x9b, 0xfe, 0x35, 0x01, 0xfe, 0x35, 0x01, + 0x42, 0x35, 0x01, 0xfe, 0x95, 0x77, 0xfe, 0x95, 0x77, 0xfe, 0x95, 0x77, 0x52, 0x95, 0x77, 0x00, + 0xd2, 0xfe, 0x70, 0x02, 0x92, 0x70, 0x02, 0x16, 0x60, 0x22, 0x00, 0x7e, 0xb2, 0x15, 0x00, 0x00, + 0x03, 0xe9, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xd0, 0x01, 0x5a, + 0xcd, 0xd1, 0x00, 0x00, 0x02, 0x55, 0x00, 0x00, 0x07, 0xd0, 0x95, 0x67, 0xe9, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x55, 0x00, 0x00, 0x02, 0x57, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x05, 0xee, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0xb8, 0xca, 0x3a, 0x6f, 0xbe, 0xd8, 0xb8, 0xca, 0x3a, 0x6f, + 0x11, 0x28, 0x08, 0x00, 0x45, 0x00, 0x05, 0xdc, 0xfe, 0x05, 0x40, 0x00, 0x40, 0x06, 0x06, 0xf4, + 0x0a, 0x01, 0x0e, 0x11, 0x0a, 0x01, 0x0e, 0x10, 0x23, 0x84, 0xfa, 0x29, 0xae, 0xd4, 0x95, 0x03, + 0x99, 0xb8, 0x77, 0xd0, 0x80, 0x10, 0x00, 0x1d, 0x6f, 0x4f, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, + 0xef, 0x1f, 0xa2, 0xcc, 0xef, 0x1f, 0xf4, 0x2c, 0xfe, 0xdb, 0x05, 0xa1, 0xdb, 0x04, 0x9e, 0xc0, + 0xfe, 0x30, 0x08, 0xb2, 0x30, 0x08, 0xda, 0x2b, 0xbd, 0xfe, 0x2a, 0x01, 0xfe, 0x2a, 0x01, 0x21, + 0x2a, 0x00, 0xb2, 0xfe, 0x57, 0xb0, 0xb6, 0x57, 0xb0, 0x14, 0x74, 0xf4, 0xf0, 0x4c, 0x05, 0x68, + 0xfe, 0x54, 0x02, 0xfe, 0x54, 0x02, 0xd2, 0x54, 0x02, 0x00, 0xbe, 0xfe, 0x32, 0x0f, 0xb6, 0x32, + 0x0f, 0x14, 0x2e, 0x16, 0xaf, 0x47, 0x00, 0x00, 0x03, 0xe9, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x94, 0x01, 0x5e, 0x5c, 0x20, 0x00, 0x00, 0x02, 0x57, 0x00, 0x00, + 0x07, 0xd0, 0xb1, 0x2f, 0xb2, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x57, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x42, 0x3c, 0x8a, + 0xb0, 0xe7, 0x54, 0x41, 0xb8, 0xca, 0x3a, 0x6f, 0xbe, 0xd8, 0x08, 0x00, 0x45, 0x00, 0x00, 0x34, + 0xa8, 0x23, 0x40, 0x00, 0x40, 0x06, 0x61, 0x7f, 0x0a, 0x01, 0x0e, 0x10, 0x0a, 0x01, 0x0f, 0x10, + 0x97, 0x91, 0x23, 0x84, 0x24, 0xfa, 0x91, 0xf7, 0xb4, 0xe8, 0xf3, 0x2d, 0x80, 0x10, 0x00, 0xab, + 0x7b, 0x7d, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0xef, 0x1f, 0xf4, 0x36, 0xef, 0x1f, 0xdc, 0xde, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xe9, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +} + +// Test collected from the SFlow reference agent. Contains dummy data for several record types +// that wern't available on an actual network for sampling. +var SFlowTestPacket2 = []byte{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, + 0x04, 0x88, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 0x38, 0x63, 0x7f, 0x00, 0x00, 0x01, 0x7f, 0x00, + 0x00, 0x01, 0xdc, 0xb8, 0x18, 0xc7, 0x04, 0x74, 0x02, 0x88, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x01, 0xc0, 0xa8, 0x5b, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, 0x3a, 0x00, 0x00, + 0xcb, 0x20, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x54, 0x00, 0x02, + 0x1f, 0x6e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x1f, 0x6e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x3f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x03, 0xed, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x6f, + 0x72, 0x67, 0x00, 0x00, 0x00, 0x0f, 0x68, 0x6f, 0x73, 0x74, 0x31, 0x2e, 0x73, 0x66, 0x6c, 0x6f, + 0x77, 0x2e, 0x6f, 0x72, 0x67, 0x06, 0x00, 0x00, 0x03, 0xec, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, + 0x00, 0x6a, 0x00, 0x00, 0x00, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x75, 0x73, 0x65, + 0x72, 0xdc, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x10, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x73, 0x65, 0x72, 0x00, 0x00, 0x03, 0xeb, 0x00, 0x00, + 0x00, 0x64, 0x00, 0x00, 0x00, 0x01, 0x0d, 0x0c, 0x0b, 0x0a, 0x00, 0x00, 0xfd, 0xe9, 0x00, 0x00, + 0x00, 0x7b, 0x00, 0x00, 0x03, 0xe7, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x01, 0xc8, 0x00, 0x00, 0x03, 0x15, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x2b, 0x67, 0x00, 0x00, 0x56, 0xce, 0x00, 0x00, + 0x82, 0x35, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x09, 0x00, 0x00, + 0x03, 0x78, 0x00, 0x00, 0x03, 0xe7, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, + 0x00, 0x0d, 0x00, 0x00, 0x01, 0xb0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x42, 0x00, 0x0c, + 0x29, 0x67, 0xa0, 0xe5, 0x00, 0x50, 0x56, 0xc0, 0x00, 0x09, 0x08, 0x00, 0x45, 0x10, 0x00, 0x34, + 0x92, 0xc3, 0x40, 0x00, 0x40, 0x06, 0x70, 0x8d, 0xc0, 0xa8, 0x5b, 0x01, 0xc0, 0xa8, 0x5b, 0x11, + 0xd3, 0xdd, 0x00, 0x16, 0xe3, 0x2e, 0x84, 0x77, 0x13, 0x6d, 0xc5, 0x53, 0x80, 0x10, 0x1f, 0xf7, + 0xe7, 0x7d, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x2e, 0xc6, 0x70, 0x3a, 0x00, 0x0f, 0x84, 0x7a, + 0xbc, 0xd2, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x90, 0x00, 0x02, 0x1f, 0x6f, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x1f, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0xed, 0x00, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x6f, 0x72, 0x67, 0x00, 0x00, + 0x00, 0x0f, 0x68, 0x6f, 0x73, 0x74, 0x31, 0x2e, 0x73, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x6f, 0x72, + 0x67, 0x03, 0x00, 0x00, 0x03, 0xec, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, + 0x00, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x77, 0x00, 0x00, + 0x00, 0x6a, 0x00, 0x00, 0x00, 0x10, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x75, 0x73, 0x65, 0x72, 0x00, 0x00, 0x03, 0xeb, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, + 0x00, 0x01, 0x0d, 0x0c, 0x0b, 0x0a, 0x00, 0x00, 0xfd, 0xe9, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, + 0x03, 0xe7, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x7b, 0x00, 0x00, 0x01, 0xc8, 0x00, 0x00, 0x03, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x2b, 0x67, 0x00, 0x00, 0x56, 0xce, 0x00, 0x00, 0x82, 0x35, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x09, 0x00, 0x00, 0x03, 0x78, 0x00, 0x00, + 0x03, 0xe7, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, + 0x01, 0xb0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x01, 0x86, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x50, 0x56, 0xc0, 0x00, 0x09, + 0x00, 0x0c, 0x29, 0x67, 0xa0, 0xe5, 0x08, 0x00, 0x45, 0x10, 0x01, 0x74, 0xbb, 0xfa, 0x40, 0x00, + 0x40, 0x06, 0x46, 0x16, 0xc0, 0xa8, 0x5b, 0x11, 0xc0, 0xa8, 0x5b, 0x01, 0x00, 0x16, 0xd3, 0xdd, + 0x13, 0x6d, 0xc5, 0x53, 0xe3, 0x2e, 0x84, 0x77, 0x80, 0x18, 0x01, 0x10, 0x38, 0xca, 0x00, 0x00, + 0x01, 0x01, 0x08, 0x0a, 0x00, 0x0f, 0x84, 0x7d, 0x2e, 0xc6, 0x70, 0x3a, 0xe3, 0x92, 0x97, 0x1a, + 0x67, 0x3b, 0xac, 0xec, 0xfa, 0x43, 0x71, 0x5e, 0x36, 0xa1, 0x0a, 0xc6, 0x1a, 0x6a, 0xed, 0x08, + 0xac, 0xf4, 0xbe, 0xd8, 0x36, 0x59, 0xf6, 0xe2, 0x3d, 0x34, 0x26, 0xf2, 0x42, 0xbd, 0x32, 0xd3, + 0x37, 0x52, 0xb8, 0xf4, 0x38, 0xf0, 0xf4, 0xeb, 0x76, 0x3b, 0xda, 0x23, 0xf1, 0x92, 0x96, 0xca, + 0xbb, 0x9c, 0x20, 0x0a, 0x38, 0x37, 0x6f, 0xd9, 0x26, 0xe6, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x01, 0x54, 0x00, 0x02, 0x1f, 0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, + 0x1f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x3f, 0xff, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x03, 0xed, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x14, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x66, 0x6c, + 0x6f, 0x77, 0x2e, 0x6f, 0x72, 0x67, 0x00, 0x00, 0x00, 0x0f, 0x68, 0x6f, 0x73, 0x74, 0x31, 0x2e, + 0x73, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x6f, 0x72, 0x67, 0xff, 0x00, 0x00, 0x03, 0xec, 0x00, 0x00, + 0x00, 0x2c, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x20, 0x75, 0x73, 0x65, 0x72, 0x77, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x10, 0x64, 0x65, + 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x73, 0x65, 0x72, 0x00, 0x00, + 0x03, 0xeb, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x01, 0x0d, 0x0c, 0x0b, 0x0a, 0x00, 0x00, + 0xfd, 0xe9, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x03, 0xe7, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x01, 0xc8, 0x00, 0x00, + 0x03, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x2b, 0x67, 0x00, 0x00, + 0x56, 0xce, 0x00, 0x00, 0x82, 0x35, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x03, 0x09, 0x00, 0x00, 0x03, 0x78, 0x00, 0x00, 0x03, 0xe7, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x01, 0xb0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x54, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x42, 0x00, 0x0c, 0x29, 0x67, 0xa0, 0xe5, 0x00, 0x50, 0x56, 0xc0, 0x00, 0x09, 0x08, 0x00, + 0x45, 0x10, 0x00, 0x34, 0x65, 0x7d, 0x40, 0x00, 0x40, 0x06, 0x9d, 0xd3, 0xc0, 0xa8, 0x5b, 0x01, + 0xc0, 0xa8, 0x5b, 0x11, 0xd3, 0xdd, 0x00, 0x16, 0xe3, 0x2e, 0x84, 0x77, 0x13, 0x6d, 0xc6, 0x93, + 0x80, 0x10, 0x1f, 0xec, 0xe6, 0x43, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x2e, 0xc6, 0x70, 0x3c, + 0x00, 0x0f, 0x84, 0x7d, 0x00, 0x50, +} + +// processor counter sample +var SFlowTestPacket3 = []byte{ + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, + 0x0a, 0x14, 0x04, 0x00, 0x00, 0x00, 0x00, 0x64, + 0x00, 0x01, 0x78, 0xe0, 0x73, 0x03, 0x48, 0x78, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x34, 0x00, 0x01, 0x78, 0xe0, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0xe9, + 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x05, 0xaa, + 0x00, 0x00, 0x05, 0x5a, 0x00, 0x00, 0x05, 0x32, + 0x00, 0x00, 0x00, 0x00, 0xe7, 0x8d, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x55, 0xe7, 0x70, 0x00, +} + +// expanded flow sample - extended switch flow record +var SFlowTestPacket4 = []byte{ + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, + 0xc0, 0xa8, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x7e, 0x32, 0xe0, 0xe4, 0x7c, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x01, 0x23, + 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x03, 0x37, 0x00, 0x00, 0x56, 0x23, + 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0xe9, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, + 0xff, 0xff, 0xff, 0xff, +} + +// expanded flow sample - extended router flow record +var SFlowTestPacket5 = []byte{ + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, + 0xc0, 0xa8, 0x01, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x7e, 0x32, 0xe0, 0xe4, 0x7c, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x01, 0x23, + 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x03, 0x34, 0x00, 0x00, 0x56, 0x02, + 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0xea, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, + 0xc0, 0xa8, 0x01, 0x21, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x80, +} + +// expanded flow sample - Ipv4 Tunnel Ingress record +var SFlowTestPacket6 = []byte{ + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x7f, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x00, 0x01, 0xbd, 0x50, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x00, 0x00, 0x00, 0x74, 0x02, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f, + 0xc0, 0xa8, 0x00, 0x54, 0xc0, 0xa8, 0x00, 0x53, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +} + +// expanded flow sample - Ipv4 Tunnel Egress record +var SFlowTestPacket7 = []byte{ + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x7f, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x42, 0x68, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x00, 0x00, 0x00, 0x12, 0x02, 0x00, 0x03, 0xe9, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, + 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x03, 0xff, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x00, 0x54, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +} + +// expanded flow sample - extended router flow record IPv6 next hop +var SFlowTestPacket8 = []byte{ + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, + 0xc0, 0xa8, 0x01, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x7e, 0x32, 0xe0, 0xe4, 0x7c, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x01, 0x23, + 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x03, 0x34, 0x00, 0x00, 0x56, 0x02, + 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0xea, + 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x02, + 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, +} + +func TestDecodeUDPSFlow(t *testing.T) { + p := gopacket.NewPacket(SFlowTestPacket1, LayerTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeUDP, LayerTypeSFlow}, t) + if got, ok := p.TransportLayer().(*UDP); ok { + want := &UDP{ + BaseLayer: BaseLayer{SFlowTestPacket1[34:42], SFlowTestPacket1[42:]}, + sPort: []byte{199, 87}, + dPort: []byte{24, 199}, + SrcPort: 51031, + DstPort: 6343, + Checksum: 8763, + Length: 1448, + } + if !reflect.DeepEqual(want, got) { + t.Errorf("UDP layer mismatch, \nwant %#v\ngot %#v\n", want, got) + } + } else { + t.Error("Transport layer packet not UDP") + } +} + +func TestDecodeSFlowDatagram(t *testing.T) { + p := gopacket.NewPacket(SFlowTestPacket1, LayerTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeUDP, LayerTypeSFlow}, t) + if got, ok := p.ApplicationLayer().(*SFlowDatagram); ok { + want := &SFlowDatagram{ + DatagramVersion: uint32(5), + AgentAddress: []byte{0xa, 0x1, 0xf8, 0x16}, + SubAgentID: uint32(17), + SequenceNumber: uint32(40443), + AgentUptime: uint32(1078576845), + SampleCount: uint32(7), + FlowSamples: []SFlowFlowSample{ + SFlowFlowSample{ + EnterpriseID: 0x0, + Format: 0x1, + SampleLength: 0xd0, + SequenceNumber: 0x2627e8, + SourceIDClass: 0x0, + SourceIDIndex: 0x213, + SamplingRate: 0x3e80, + SamplePool: 0x50bde580, + Dropped: 0x0, + InputInterface: 0x213, + OutputInterface: 0x0, + RecordCount: 0x2, + Records: []SFlowRecord{ + SFlowRawPacketFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0x0, + Format: 0x1, + FlowDataLength: 0x90, + }, + HeaderProtocol: 0x1, + FrameLength: 0x5d2, + PayloadRemoved: 0x4, + HeaderLength: 0x80, + Header: gopacket.NewPacket(SFlowTestPacket1[134:262], LayerTypeEthernet, gopacket.Default), + }, + SFlowExtendedSwitchFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0x0, + Format: 0x3e9, + FlowDataLength: 0x10, + }, + IncomingVLAN: 0x202, + IncomingVLANPriority: 0x0, + OutgoingVLAN: 0x0, + OutgoingVLANPriority: 0x0, + }, + }, + }, + SFlowFlowSample{ + EnterpriseID: 0x0, + Format: 0x1, + SampleLength: 0xd0, + SequenceNumber: 0x15e5c1e, + SourceIDClass: 0x0, + SourceIDIndex: 0x257, + SamplingRate: 0x7d0, + SamplePool: 0xb12fa290, + Dropped: 0x0, + InputInterface: 0x257, + OutputInterface: 0x0, + RecordCount: 0x2, + Records: []SFlowRecord{ + SFlowRawPacketFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0x0, + Format: 0x1, + FlowDataLength: 0x90, + }, + HeaderProtocol: 0x1, + FrameLength: 0x5ee, + PayloadRemoved: 0x4, + HeaderLength: 0x80, + Header: gopacket.NewPacket(SFlowTestPacket1[350:478], LayerTypeEthernet, gopacket.Default), + }, + SFlowExtendedSwitchFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0x0, + Format: 0x3e9, + FlowDataLength: 0x10, + }, + IncomingVLAN: 0x202, + IncomingVLANPriority: 0x0, + OutgoingVLAN: 0x0, + OutgoingVLANPriority: 0x0, + }, + }, + }, + SFlowFlowSample{ + EnterpriseID: 0x0, + Format: 0x1, + SampleLength: 0xd0, + SequenceNumber: 0x15acdd0, + SourceIDClass: 0x0, + SourceIDIndex: 0x255, + SamplingRate: 0x7d0, + SamplePool: 0x9567e130, + Dropped: 0x0, + InputInterface: 0x255, + OutputInterface: 0x0, + RecordCount: 0x2, + Records: []SFlowRecord{ + SFlowRawPacketFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0x0, + Format: 0x1, + FlowDataLength: 0x90, + }, + HeaderProtocol: 0x1, + FrameLength: 0x446, + PayloadRemoved: 0x4, + HeaderLength: 0x80, + Header: gopacket.NewPacket(SFlowTestPacket1[566:694], LayerTypeEthernet, gopacket.Default), + }, + SFlowExtendedSwitchFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0x0, + Format: 0x3e9, + FlowDataLength: 0x10, + }, + IncomingVLAN: 0x202, + IncomingVLANPriority: 0x0, + OutgoingVLAN: 0x0, + OutgoingVLANPriority: 0x0, + }, + }, + }, + SFlowFlowSample{ + EnterpriseID: 0x0, + Format: 0x1, + SampleLength: 0xd0, + SequenceNumber: 0x15e5c1f, + SourceIDClass: 0x0, + SourceIDIndex: 0x257, + SamplingRate: 0x7d0, + SamplePool: 0xb12faa60, + Dropped: 0x0, + InputInterface: 0x257, + OutputInterface: 0x0, + RecordCount: 0x2, + Records: []SFlowRecord{ + SFlowRawPacketFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0x0, + Format: 0x1, + FlowDataLength: 0x90, + }, + HeaderProtocol: 0x1, + FrameLength: 0x5ee, + PayloadRemoved: 0x4, + HeaderLength: 0x80, + Header: gopacket.NewPacket(SFlowTestPacket1[958:1086], LayerTypeEthernet, gopacket.Default), + }, + SFlowExtendedSwitchFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0x0, + Format: 0x3e9, + FlowDataLength: 0x10, + }, + IncomingVLAN: 0x202, + IncomingVLANPriority: 0x0, + OutgoingVLAN: 0x0, + OutgoingVLANPriority: 0x0, + }, + }, + }, + SFlowFlowSample{ + EnterpriseID: 0x0, + Format: 0x1, + SampleLength: 0xd0, + SequenceNumber: 0x15acdd1, + SourceIDClass: 0x0, + SourceIDIndex: 0x255, + SamplingRate: 0x7d0, + SamplePool: 0x9567e900, + Dropped: 0x0, + InputInterface: 0x255, + OutputInterface: 0x257, + RecordCount: 0x2, + Records: []SFlowRecord{ + SFlowRawPacketFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0x0, + Format: 0x1, + FlowDataLength: 0x90, + }, + HeaderProtocol: 0x1, + FrameLength: 0x5ee, + PayloadRemoved: 0x4, + HeaderLength: 0x80, + Header: gopacket.NewPacket(SFlowTestPacket1[1174:1302], LayerTypeEthernet, gopacket.Default), + }, + SFlowExtendedSwitchFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0x0, + Format: 0x3e9, + FlowDataLength: 0x10, + }, + IncomingVLAN: 0x202, + IncomingVLANPriority: 0x0, + OutgoingVLAN: 0x202, + OutgoingVLANPriority: 0x0, + }, + }, + }, + SFlowFlowSample{ + EnterpriseID: 0x0, + Format: 0x1, + SampleLength: 0x94, + SequenceNumber: 0x15e5c20, + SourceIDClass: 0x0, + SourceIDIndex: 0x257, + SamplingRate: 0x7d0, + SamplePool: 0xb12fb230, + Dropped: 0x0, + InputInterface: 0x257, + OutputInterface: 0x0, + RecordCount: 0x2, + Records: []SFlowRecord{ + SFlowRawPacketFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0x0, + Format: 0x1, + FlowDataLength: 0x54, + }, + HeaderProtocol: 0x1, + FrameLength: 0x46, + PayloadRemoved: 0x4, + HeaderLength: 0x42, + Header: gopacket.NewPacket(SFlowTestPacket1[1390:1458], LayerTypeEthernet, gopacket.Default), + }, + SFlowExtendedSwitchFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0x0, + Format: 0x3e9, + FlowDataLength: 0x10, + }, + IncomingVLAN: 0x202, + IncomingVLANPriority: 0x0, + OutgoingVLAN: 0x0, + OutgoingVLANPriority: 0x0, + }, + }, + }, + }, + CounterSamples: []SFlowCounterSample{ + SFlowCounterSample{ + Format: 0x2, + SampleLength: 0xa8, + SequenceNumber: 0x20f2, + SourceIDClass: 0x0, + SourceIDIndex: 0x20a, + RecordCount: 0x2, + Records: []SFlowRecord{ + SFlowGenericInterfaceCounters{ + SFlowBaseCounterRecord: SFlowBaseCounterRecord{ + EnterpriseID: 0x0, + Format: 0x1, + FlowDataLength: 0x58, + }, + IfIndex: 0x20a, + IfType: 0x6, + IfSpeed: 0x2540be400, + IfDirection: 0x1, + IfStatus: 0x3, + IfInOctets: 0x129826db06c0b, + IfInUcastPkts: 0xcb0ddd96, + IfInMulticastPkts: 0x6a8c6, + IfInBroadcastPkts: 0x7b, + IfInDiscards: 0x0, + IfInErrors: 0x0, + IfInUnknownProtos: 0x0, + IfOutOctets: 0x340235587c9e, + IfOutUcastPkts: 0x56642571, + IfOutMulticastPkts: 0x705ac4, + IfOutBroadcastPkts: 0x908f1, + IfOutDiscards: 0x0, + IfOutErrors: 0x0, + IfPromiscuousMode: 0x0, + }, + SFlowEthernetCounters{ + SFlowBaseCounterRecord: SFlowBaseCounterRecord{ + EnterpriseID: 0x0, + Format: 0x2, + FlowDataLength: 0x34, + }, + AlignmentErrors: 0x0, + FCSErrors: 0x0, + SingleCollisionFrames: 0x0, + MultipleCollisionFrames: 0x0, + SQETestErrors: 0x0, + DeferredTransmissions: 0x0, + LateCollisions: 0x0, + ExcessiveCollisions: 0x0, + InternalMacTransmitErrors: 0x0, + CarrierSenseErrors: 0x0, + FrameTooLongs: 0x0, + InternalMacReceiveErrors: 0x0, + SymbolErrors: 0x0, + }, + }, + }, + }, + } + if !reflect.DeepEqual(want, got) { + t.Errorf("SFlow layer mismatch, \nwant:\n\n%#v\ngot:\n\n\n%#v\n\n", want, got) + } + } else { + t.Error("Application layer packet not UDP") + } +} + +func TestPacketPacket0(t *testing.T) { + p := gopacket.NewPacket(SFlowTestPacket2, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeUDP, LayerTypeSFlow}, t) + if got, ok := p.ApplicationLayer().(*SFlowDatagram); ok { + want := &SFlowDatagram{ + DatagramVersion: uint32(5), + AgentAddress: []byte{192, 168, 91, 17}, + SubAgentID: uint32(0), + SequenceNumber: uint32(46394), + AgentUptime: uint32(52000), + SampleCount: uint32(3), + FlowSamples: []SFlowFlowSample{ + SFlowFlowSample{ + EnterpriseID: 0x0, + Format: 0x1, + SampleLength: 340, + SequenceNumber: 139118, + SourceIDClass: 0, + SourceIDIndex: 3, + SamplingRate: 1, + SamplePool: 139118, + Dropped: 0, + InputInterface: 3, + OutputInterface: 1073741823, + RecordCount: 4, + Records: []SFlowRecord{ + SFlowExtendedURLRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0, + Format: 1005, + FlowDataLength: 48, + }, + Direction: SFlowURLsrc, + URL: "http://www.sflow.org", + Host: "host1.sflow.org", + }, + SFlowExtendedUserFlow{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0, + Format: 1004, + FlowDataLength: 44, + }, + SourceCharSet: SFlowCSUTF8, + SourceUserID: "source user", + DestinationCharSet: SFlowCSUTF8, + DestinationUserID: "destination user", + }, + SFlowExtendedGatewayFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0, + Format: 1003, + FlowDataLength: 100, + }, + NextHop: []byte{0x0d, 0x0c, 0x0b, 0x0a}, + AS: 65001, + SourceAS: 123, + PeerAS: 999, + ASPathCount: 3, + ASPath: []SFlowASDestination{ + SFlowASDestination{ + Type: SFlowASSequence, + Count: 3, + Members: []uint32{123, 456, 789}, + }, + SFlowASDestination{ + Type: SFlowASSet, + Count: 3, + Members: []uint32{11111, 22222, 33333}, + }, + SFlowASDestination{ + Type: SFlowASSequence, + Count: 3, + Members: []uint32{777, 888, 999}, + }, + }, + Communities: []uint32{12, 13}, + LocalPref: 432, + }, + SFlowRawPacketFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0x0, + Format: 0x1, + FlowDataLength: 84, + }, + HeaderProtocol: 1, + FrameLength: 70, + PayloadRemoved: 4, + HeaderLength: 0x42, + Header: gopacket.NewPacket(SFlowTestPacket2[350:418], LayerTypeEthernet, gopacket.Default), + }, + }, + }, + SFlowFlowSample{ + EnterpriseID: 0x0, + Format: 0x1, + SampleLength: 400, + SequenceNumber: 139119, + SourceIDClass: 0, + SourceIDIndex: 3, + SamplingRate: 1, + SamplePool: 139119, + Dropped: 0, + InputInterface: 1073741823, + OutputInterface: 3, + RecordCount: 4, + Records: []SFlowRecord{ + SFlowExtendedURLRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0, + Format: 1005, + FlowDataLength: 48, + }, + Direction: SFlowURLsrc, + URL: "http://www.sflow.org", + Host: "host1.sflow.org", + }, + SFlowExtendedUserFlow{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0, + Format: 1004, + FlowDataLength: 44, + }, + SourceCharSet: SFlowCSUTF8, + SourceUserID: "source user", + DestinationCharSet: SFlowCSUTF8, + DestinationUserID: "destination user", + }, + SFlowExtendedGatewayFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0, + Format: 1003, + FlowDataLength: 100, + }, + NextHop: []byte{0x0d, 0x0c, 0x0b, 0x0a}, + AS: 65001, + SourceAS: 123, + PeerAS: 999, + ASPathCount: 3, + ASPath: []SFlowASDestination{ + SFlowASDestination{ + Type: SFlowASSequence, + Count: 3, + Members: []uint32{123, 456, 789}, + }, + SFlowASDestination{ + Type: SFlowASSet, + Count: 3, + Members: []uint32{11111, 22222, 33333}, + }, + SFlowASDestination{ + Type: SFlowASSequence, + Count: 3, + Members: []uint32{777, 888, 999}, + }, + }, + Communities: []uint32{12, 13}, + LocalPref: 432, + }, + SFlowRawPacketFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0x0, + Format: 0x1, + FlowDataLength: 144, + }, + HeaderProtocol: 1, + FrameLength: 390, + PayloadRemoved: 4, + HeaderLength: 0x80, + Header: gopacket.NewPacket(SFlowTestPacket2[698:826], LayerTypeEthernet, gopacket.Default), + }, + }, + }, + SFlowFlowSample{ + EnterpriseID: 0x0, + Format: 0x1, + SampleLength: 340, + SequenceNumber: 139120, + SourceIDClass: 0, + SourceIDIndex: 3, + SamplingRate: 1, + SamplePool: 139120, + Dropped: 0, + InputInterface: 3, + OutputInterface: 1073741823, + RecordCount: 4, + Records: []SFlowRecord{ + SFlowExtendedURLRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0, + Format: 1005, + FlowDataLength: 48, + }, + Direction: SFlowURLsrc, + URL: "http://www.sflow.org", + Host: "host1.sflow.org", + }, + SFlowExtendedUserFlow{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0, + Format: 1004, + FlowDataLength: 44, + }, + SourceCharSet: SFlowCSUTF8, + SourceUserID: "source user", + DestinationCharSet: SFlowCSUTF8, + DestinationUserID: "destination user", + }, + SFlowExtendedGatewayFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0, + Format: 1003, + FlowDataLength: 100, + }, + NextHop: []byte{0x0d, 0x0c, 0x0b, 0x0a}, + AS: 65001, + SourceAS: 123, + PeerAS: 999, + ASPathCount: 3, + ASPath: []SFlowASDestination{ + SFlowASDestination{ + Type: SFlowASSequence, + Count: 3, + Members: []uint32{123, 456, 789}, + }, + SFlowASDestination{ + Type: SFlowASSet, + Count: 3, + Members: []uint32{11111, 22222, 33333}, + }, + SFlowASDestination{ + Type: SFlowASSequence, + Count: 3, + Members: []uint32{777, 888, 999}, + }, + }, + Communities: []uint32{12, 13}, + LocalPref: 432, + }, + SFlowRawPacketFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0x0, + Format: 0x1, + FlowDataLength: 84, + }, + HeaderProtocol: 1, + FrameLength: 70, + PayloadRemoved: 4, + HeaderLength: 0x42, + Header: gopacket.NewPacket(SFlowTestPacket2[1106:1174], LayerTypeEthernet, gopacket.Default), + }, + }, + }, + }, + } + if !reflect.DeepEqual(want, got) { + t.Errorf("SFlow layer mismatch, \nwant:\n\n%#v\ngot:\n\n\n%#v\n\n", want, got) + } + } else { + t.Error("Application layer packet not UDP") + } +} + +func TestDecodeProcessorCounter(t *testing.T) { + p := gopacket.NewPacket(SFlowTestPacket3, LayerTypeSFlow, gopacket.Default) + + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeSFlow}, t) + + got := p.ApplicationLayer().(*SFlowDatagram) + + want := &SFlowDatagram{ + DatagramVersion: uint32(5), + AgentAddress: []byte{0x0a, 0x14, 0x04, 0x00}, + SubAgentID: uint32(0x64), + SequenceNumber: uint32(96480), + AgentUptime: uint32(1929595000), + SampleCount: uint32(1), + CounterSamples: []SFlowCounterSample{ + SFlowCounterSample{ + Format: SFlowTypeExpandedCounterSample, + SampleLength: 0x34, + SequenceNumber: 0x0178e0, + SourceIDClass: 0x00, + SourceIDIndex: 0x01, + RecordCount: 0x01, + Records: []SFlowRecord{ + SFlowProcessorCounters{ + SFlowBaseCounterRecord: SFlowBaseCounterRecord{ + EnterpriseID: 0x0, + Format: SFlowTypeProcessorCounters, + FlowDataLength: 0x1c, + }, + FiveSecCpu: 0x05aa, + OneMinCpu: 0x055a, + FiveMinCpu: 0x0532, + TotalMemory: 0xe78d7000, + FreeMemory: 0x55e77000, + }, + }, + }, + }, + } + if !reflect.DeepEqual(want, got) { + t.Errorf("SFlow layer mismatch, \nwant:\n\n%#v\ngot:\n\n\n%#v\n\n", want, got) + } +} + +func TestDecodeExtendedSwitchFlow(t *testing.T) { + p := gopacket.NewPacket(SFlowTestPacket4, LayerTypeSFlow, gopacket.Default) + + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeSFlow}, t) + + got := p.ApplicationLayer().(*SFlowDatagram) + + want := &SFlowDatagram{ + DatagramVersion: uint32(5), + AgentAddress: []byte{0xc0, 0xa8, 0x01, 0x07}, + SubAgentID: uint32(0x00), + SequenceNumber: uint32(0x027e), + AgentUptime: uint32(0x32e0e47c), + SampleCount: uint32(1), + FlowSamples: []SFlowFlowSample{ + SFlowFlowSample{ + Format: SFlowTypeFlowSample, + SampleLength: 0x38, + SequenceNumber: 0x123, + SourceIDClass: 0x00, + SourceIDIndex: 0x1d, + SamplingRate: 0x100, + SamplePool: 0x337, + Dropped: 0x5623, + InputInterfaceFormat: 0x00, + InputInterface: 0x1d, + OutputInterfaceFormat: 0x00, + OutputInterface: 0x04, + RecordCount: 0x01, + Records: []SFlowRecord{ + SFlowExtendedSwitchFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0x0, + Format: SFlowTypeExtendedSwitchFlow, + FlowDataLength: 0x10, + }, + IncomingVLAN: 0x03, + IncomingVLANPriority: 0x02, + OutgoingVLAN: 0x05, + OutgoingVLANPriority: 0xffffffff, + }, + }, + }, + }, + } + if !reflect.DeepEqual(want, got) { + t.Errorf("SFlow layer mismatch, \nwant:\n\n%#v\ngot:\n\n\n%#v\n\n", want, got) + } +} + +func TestDecodeExtendedRouterFlow(t *testing.T) { + p := gopacket.NewPacket(SFlowTestPacket5, LayerTypeSFlow, gopacket.Default) + + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeSFlow}, t) + + got := p.ApplicationLayer().(*SFlowDatagram) + + want := &SFlowDatagram{ + DatagramVersion: uint32(5), + AgentAddress: []byte{0xc0, 0xa8, 0x01, 0x12}, + SubAgentID: uint32(0x00), + SequenceNumber: uint32(0x027e), + AgentUptime: uint32(0x32e0e47c), + SampleCount: uint32(1), + FlowSamples: []SFlowFlowSample{ + SFlowFlowSample{ + Format: SFlowTypeFlowSample, + SampleLength: 0x34, + SequenceNumber: 0x123, + SourceIDClass: 0x00, + SourceIDIndex: 0x1d, + SamplingRate: 0x100, + SamplePool: 0x334, + Dropped: 0x5602, + InputInterfaceFormat: 0x00, + InputInterface: 0x1d, + OutputInterfaceFormat: 0x00, + OutputInterface: 0x04, + RecordCount: 0x01, + Records: []SFlowRecord{ + SFlowExtendedRouterFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0x0, + Format: SFlowTypeExtendedRouterFlow, + FlowDataLength: 0x10, + }, + NextHop: []byte{0xc0, 0xa8, 0x01, 0x21}, + NextHopSourceMask: 0xffffffff, + NextHopDestinationMask: 0xffffff80, + }, + }, + }, + }, + } + if !reflect.DeepEqual(want, got) { + t.Errorf("SFlow layer mismatch, \nwant:\n\n%#v\ngot:\n\n\n%#v\n\n", want, got) + } +} + +func TestDecodeExtendedRouterFlowIPv6(t *testing.T) { + p := gopacket.NewPacket(SFlowTestPacket8, LayerTypeSFlow, gopacket.Default) + + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeSFlow}, t) + + got := p.ApplicationLayer().(*SFlowDatagram) + + want := &SFlowDatagram{ + DatagramVersion: uint32(5), + AgentAddress: []byte{0xc0, 0xa8, 0x01, 0x12}, + SubAgentID: uint32(0x00), + SequenceNumber: uint32(0x027e), + AgentUptime: uint32(0x32e0e47c), + SampleCount: uint32(1), + FlowSamples: []SFlowFlowSample{ + SFlowFlowSample{ + Format: SFlowTypeFlowSample, + SampleLength: 0x34, + SequenceNumber: 0x123, + SourceIDClass: 0x00, + SourceIDIndex: 0x1d, + SamplingRate: 0x100, + SamplePool: 0x334, + Dropped: 0x5602, + InputInterfaceFormat: 0x00, + InputInterface: 0x1d, + OutputInterfaceFormat: 0x00, + OutputInterface: 0x04, + RecordCount: 0x01, + Records: []SFlowRecord{ + SFlowExtendedRouterFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0x0, + Format: SFlowTypeExtendedRouterFlow, + FlowDataLength: 0x1c, + }, + NextHop: []byte{0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + NextHopSourceMask: 0xffffffff, + NextHopDestinationMask: 0xffffff80, + }, + }, + }, + }, + } + if !reflect.DeepEqual(want, got) { + t.Errorf("SFlow layer mismatch, \nwant:\n\n%#v\ngot:\n\n\n%#v\n\n", want, got) + } +} + +func TestDecodeExtendedIpv4TunnelIngressFlow(t *testing.T) { + p := gopacket.NewPacket(SFlowTestPacket6, LayerTypeSFlow, gopacket.Default) + + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeSFlow}, t) + + got := p.ApplicationLayer().(*SFlowDatagram) + + want := &SFlowDatagram{ + DatagramVersion: uint32(5), + AgentAddress: []byte{0x7f, 0x0, 0x0, 0x1}, + SubAgentID: uint32(0), + SequenceNumber: uint32(0x72), + AgentUptime: uint32(0x1bd50), + SampleCount: uint32(1), + FlowSamples: []SFlowFlowSample{ + SFlowFlowSample{ + Format: SFlowTypeFlowSample, + SampleLength: 0x48, + SequenceNumber: 0x74, + SourceIDClass: 0x0, + SourceIDIndex: 0x20003e8, + SamplingRate: 0x1, + SamplePool: 0x74, + Dropped: 0x0, + InputInterfaceFormat: 0x0, + InputInterface: 0x0, + OutputInterfaceFormat: 0x0, + OutputInterface: 0x80000001, + RecordCount: 0x1, + Records: []SFlowRecord{ + SFlowExtendedIpv4TunnelIngressRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0x0, + Format: SFlowTypeExtendedIpv4TunnelIngressFlow, + FlowDataLength: 0x20, + }, + SFlowIpv4Record: SFlowIpv4Record{ + Length: 0x0, + Protocol: 0x2f, + IPSrc: net.IP{0xc0, 0xa8, 0x0, 0x54}, + IPDst: net.IP{0xc0, 0xa8, 0x0, 0x53}, + PortSrc: 0x0, + PortDst: 0x0, + TCPFlags: 0x0, + TOS: 0x0, + }, + }, + }, + }, + }, + } + if !reflect.DeepEqual(want, got) { + t.Errorf("SFlow layer mismatch, \nwant:\n\n%#v\ngot:\n\n\n%#v\n\n", want, got) + } +} + +func TestDecodeExtendedIpv4TunnelEgressFlow(t *testing.T) { + p := gopacket.NewPacket(SFlowTestPacket7, LayerTypeSFlow, gopacket.Default) + + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeSFlow}, t) + + got := p.ApplicationLayer().(*SFlowDatagram) + + want := &SFlowDatagram{ + DatagramVersion: uint32(5), + AgentAddress: []byte{0x7f, 0x0, 0x0, 0x1}, + SubAgentID: uint32(1), + SequenceNumber: uint32(0x12), + AgentUptime: uint32(0x4268), + SampleCount: uint32(1), + FlowSamples: []SFlowFlowSample{ + SFlowFlowSample{ + Format: SFlowTypeFlowSample, + SampleLength: 0x48, + SequenceNumber: 0x12, + SourceIDClass: 0x0, + SourceIDIndex: 0x20003e9, + SamplingRate: 0x1, + SamplePool: 0x12, + Dropped: 0x0, + InputInterfaceFormat: 0x0, + InputInterface: 0x6c, + OutputInterfaceFormat: 0x0, + OutputInterface: 0x80000001, + RecordCount: 0x1, + Records: []SFlowRecord{ + SFlowExtendedIpv4TunnelEgressRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0x0, + Format: SFlowTypeExtendedIpv4TunnelEgressFlow, + FlowDataLength: 0x20, + }, + SFlowIpv4Record: SFlowIpv4Record{ + Length: 0x0, + Protocol: 0x0, + IPSrc: net.IP{0x0, 0x0, 0x0, 0x0}, + IPDst: net.IP{0xc0, 0xa8, 0x0, 0x54}, + PortSrc: 0x0, + PortDst: 0x0, + TCPFlags: 0x0, + TOS: 0x0, + }, + }, + }, + }, + }, + } + if !reflect.DeepEqual(want, got) { + t.Errorf("SFlow layer mismatch, \nwant:\n\n%#v\ngot:\n\n\n%#v\n\n", want, got) + } +} + +func BenchmarkDecodeSFlowPacket1(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(SFlowTestPacket1, LinkTypeEthernet, gopacket.NoCopy) + } +} + +func BenchmarkDecodeSFlowPacket2(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(SFlowTestPacket2, LinkTypeEthernet, gopacket.NoCopy) + } +} + +func BenchmarkDecodeSFlowPacket3(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(SFlowTestPacket3, LinkTypeEthernet, gopacket.NoCopy) + } +} + +func BenchmarkDecodeSFlowPacket4(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(SFlowTestPacket4, LinkTypeEthernet, gopacket.NoCopy) + } +} + +func BenchmarkDecodeSFlowLayerPacket1(b *testing.B) { + var sflow SFlowDatagram + for i := 0; i < b.N; i++ { + sflow.DecodeFromBytes(SFlowTestPacket1[ /*eth*/ 14+ /*ipv4*/ 20+ /*udp*/ 8:], gopacket.NilDecodeFeedback) + } +} + +func BenchmarkDecodeSFlowLayerPacket2(b *testing.B) { + var sflow SFlowDatagram + for i := 0; i < b.N; i++ { + sflow.DecodeFromBytes(SFlowTestPacket2[ /*eth*/ 14+ /*ipv4*/ 20+ /*udp*/ 8:], gopacket.NilDecodeFeedback) + } +} diff --git a/vendor/github.com/google/gopacket/layers/stp.go b/vendor/github.com/google/gopacket/layers/stp.go new file mode 100644 index 0000000..bde7d7c --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/stp.go @@ -0,0 +1,27 @@ +// Copyright 2017 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "github.com/google/gopacket" +) + +// STP decode spanning tree protocol packets to transport BPDU (bridge protocol data unit) message. +type STP struct { + BaseLayer +} + +// LayerType returns gopacket.LayerTypeSTP. +func (s *STP) LayerType() gopacket.LayerType { return LayerTypeSTP } + +func decodeSTP(data []byte, p gopacket.PacketBuilder) error { + stp := &STP{} + stp.Contents = data[:] + // TODO: parse the STP protocol into actual subfields. + p.AddLayer(stp) + return nil +} diff --git a/vendor/github.com/google/gopacket/layers/tcp.go b/vendor/github.com/google/gopacket/layers/tcp.go new file mode 100644 index 0000000..fb731da --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/tcp.go @@ -0,0 +1,327 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// Copyright 2009-2011 Andreas Krennmair. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "encoding/hex" + "errors" + "fmt" + + "github.com/google/gopacket" +) + +// TCP is the layer for TCP headers. +type TCP struct { + BaseLayer + SrcPort, DstPort TCPPort + Seq uint32 + Ack uint32 + DataOffset uint8 + FIN, SYN, RST, PSH, ACK, URG, ECE, CWR, NS bool + Window uint16 + Checksum uint16 + Urgent uint16 + sPort, dPort []byte + Options []TCPOption + Padding []byte + opts [4]TCPOption + tcpipchecksum +} + +// TCPOptionKind represents a TCP option code. +type TCPOptionKind uint8 + +const ( + TCPOptionKindEndList = 0 + TCPOptionKindNop = 1 + TCPOptionKindMSS = 2 // len = 4 + TCPOptionKindWindowScale = 3 // len = 3 + TCPOptionKindSACKPermitted = 4 // len = 2 + TCPOptionKindSACK = 5 // len = n + TCPOptionKindEcho = 6 // len = 6, obsolete + TCPOptionKindEchoReply = 7 // len = 6, obsolete + TCPOptionKindTimestamps = 8 // len = 10 + TCPOptionKindPartialOrderConnectionPermitted = 9 // len = 2, obsolete + TCPOptionKindPartialOrderServiceProfile = 10 // len = 3, obsolete + TCPOptionKindCC = 11 // obsolete + TCPOptionKindCCNew = 12 // obsolete + TCPOptionKindCCEcho = 13 // obsolete + TCPOptionKindAltChecksum = 14 // len = 3, obsolete + TCPOptionKindAltChecksumData = 15 // len = n, obsolete +) + +func (k TCPOptionKind) String() string { + switch k { + case TCPOptionKindEndList: + return "EndList" + case TCPOptionKindNop: + return "NOP" + case TCPOptionKindMSS: + return "MSS" + case TCPOptionKindWindowScale: + return "WindowScale" + case TCPOptionKindSACKPermitted: + return "SACKPermitted" + case TCPOptionKindSACK: + return "SACK" + case TCPOptionKindEcho: + return "Echo" + case TCPOptionKindEchoReply: + return "EchoReply" + case TCPOptionKindTimestamps: + return "Timestamps" + case TCPOptionKindPartialOrderConnectionPermitted: + return "PartialOrderConnectionPermitted" + case TCPOptionKindPartialOrderServiceProfile: + return "PartialOrderServiceProfile" + case TCPOptionKindCC: + return "CC" + case TCPOptionKindCCNew: + return "CCNew" + case TCPOptionKindCCEcho: + return "CCEcho" + case TCPOptionKindAltChecksum: + return "AltChecksum" + case TCPOptionKindAltChecksumData: + return "AltChecksumData" + default: + return fmt.Sprintf("Unknown(%d)", k) + } +} + +type TCPOption struct { + OptionType TCPOptionKind + OptionLength uint8 + OptionData []byte +} + +func (t TCPOption) String() string { + hd := hex.EncodeToString(t.OptionData) + if len(hd) > 0 { + hd = " 0x" + hd + } + switch t.OptionType { + case TCPOptionKindMSS: + return fmt.Sprintf("TCPOption(%s:%v%s)", + t.OptionType, + binary.BigEndian.Uint16(t.OptionData), + hd) + + case TCPOptionKindTimestamps: + if len(t.OptionData) == 8 { + return fmt.Sprintf("TCPOption(%s:%v/%v%s)", + t.OptionType, + binary.BigEndian.Uint32(t.OptionData[:4]), + binary.BigEndian.Uint32(t.OptionData[4:8]), + hd) + } + } + return fmt.Sprintf("TCPOption(%s:%s)", t.OptionType, hd) +} + +// LayerType returns gopacket.LayerTypeTCP +func (t *TCP) LayerType() gopacket.LayerType { return LayerTypeTCP } + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (t *TCP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + var optionLength int + for _, o := range t.Options { + switch o.OptionType { + case 0, 1: + optionLength += 1 + default: + optionLength += 2 + len(o.OptionData) + } + } + if opts.FixLengths { + if rem := optionLength % 4; rem != 0 { + t.Padding = lotsOfZeros[:4-rem] + } + t.DataOffset = uint8((len(t.Padding) + optionLength + 20) / 4) + } + bytes, err := b.PrependBytes(20 + optionLength + len(t.Padding)) + if err != nil { + return err + } + binary.BigEndian.PutUint16(bytes, uint16(t.SrcPort)) + binary.BigEndian.PutUint16(bytes[2:], uint16(t.DstPort)) + binary.BigEndian.PutUint32(bytes[4:], t.Seq) + binary.BigEndian.PutUint32(bytes[8:], t.Ack) + binary.BigEndian.PutUint16(bytes[12:], t.flagsAndOffset()) + binary.BigEndian.PutUint16(bytes[14:], t.Window) + binary.BigEndian.PutUint16(bytes[18:], t.Urgent) + start := 20 + for _, o := range t.Options { + bytes[start] = byte(o.OptionType) + switch o.OptionType { + case 0, 1: + start++ + default: + if opts.FixLengths { + o.OptionLength = uint8(len(o.OptionData) + 2) + } + bytes[start+1] = o.OptionLength + copy(bytes[start+2:start+len(o.OptionData)+2], o.OptionData) + start += int(o.OptionLength) + } + } + copy(bytes[start:], t.Padding) + if opts.ComputeChecksums { + // zero out checksum bytes in current serialization. + bytes[16] = 0 + bytes[17] = 0 + csum, err := t.computeChecksum(b.Bytes(), IPProtocolTCP) + if err != nil { + return err + } + t.Checksum = csum + } + binary.BigEndian.PutUint16(bytes[16:], t.Checksum) + return nil +} + +func (t *TCP) ComputeChecksum() (uint16, error) { + return t.computeChecksum(append(t.Contents, t.Payload...), IPProtocolTCP) +} + +func (t *TCP) flagsAndOffset() uint16 { + f := uint16(t.DataOffset) << 12 + if t.FIN { + f |= 0x0001 + } + if t.SYN { + f |= 0x0002 + } + if t.RST { + f |= 0x0004 + } + if t.PSH { + f |= 0x0008 + } + if t.ACK { + f |= 0x0010 + } + if t.URG { + f |= 0x0020 + } + if t.ECE { + f |= 0x0040 + } + if t.CWR { + f |= 0x0080 + } + if t.NS { + f |= 0x0100 + } + return f +} + +func (tcp *TCP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + tcp.SrcPort = TCPPort(binary.BigEndian.Uint16(data[0:2])) + tcp.sPort = data[0:2] + tcp.DstPort = TCPPort(binary.BigEndian.Uint16(data[2:4])) + tcp.dPort = data[2:4] + tcp.Seq = binary.BigEndian.Uint32(data[4:8]) + tcp.Ack = binary.BigEndian.Uint32(data[8:12]) + tcp.DataOffset = data[12] >> 4 + tcp.FIN = data[13]&0x01 != 0 + tcp.SYN = data[13]&0x02 != 0 + tcp.RST = data[13]&0x04 != 0 + tcp.PSH = data[13]&0x08 != 0 + tcp.ACK = data[13]&0x10 != 0 + tcp.URG = data[13]&0x20 != 0 + tcp.ECE = data[13]&0x40 != 0 + tcp.CWR = data[13]&0x80 != 0 + tcp.NS = data[12]&0x01 != 0 + tcp.Window = binary.BigEndian.Uint16(data[14:16]) + tcp.Checksum = binary.BigEndian.Uint16(data[16:18]) + tcp.Urgent = binary.BigEndian.Uint16(data[18:20]) + tcp.Options = tcp.opts[:0] + if tcp.DataOffset < 5 { + return fmt.Errorf("Invalid TCP data offset %d < 5", tcp.DataOffset) + } + dataStart := int(tcp.DataOffset) * 4 + if dataStart > len(data) { + df.SetTruncated() + tcp.Payload = nil + tcp.Contents = data + return errors.New("TCP data offset greater than packet length") + } + tcp.Contents = data[:dataStart] + tcp.Payload = data[dataStart:] + // From here on, data points just to the header options. + data = data[20:dataStart] + for len(data) > 0 { + if tcp.Options == nil { + // Pre-allocate to avoid allocating a slice. + tcp.Options = tcp.opts[:0] + } + tcp.Options = append(tcp.Options, TCPOption{OptionType: TCPOptionKind(data[0])}) + opt := &tcp.Options[len(tcp.Options)-1] + switch opt.OptionType { + case TCPOptionKindEndList: // End of options + opt.OptionLength = 1 + tcp.Padding = data[1:] + break + case TCPOptionKindNop: // 1 byte padding + opt.OptionLength = 1 + default: + opt.OptionLength = data[1] + if opt.OptionLength < 2 { + return fmt.Errorf("Invalid TCP option length %d < 2", opt.OptionLength) + } else if int(opt.OptionLength) > len(data) { + return fmt.Errorf("Invalid TCP option length %d exceeds remaining %d bytes", opt.OptionLength, len(data)) + } + opt.OptionData = data[2:opt.OptionLength] + } + data = data[opt.OptionLength:] + } + return nil +} + +func (t *TCP) CanDecode() gopacket.LayerClass { + return LayerTypeTCP +} + +func (t *TCP) NextLayerType() gopacket.LayerType { + lt := t.DstPort.LayerType() + if lt == gopacket.LayerTypePayload { + lt = t.SrcPort.LayerType() + } + return lt +} + +func decodeTCP(data []byte, p gopacket.PacketBuilder) error { + tcp := &TCP{} + err := tcp.DecodeFromBytes(data, p) + p.AddLayer(tcp) + p.SetTransportLayer(tcp) + if err != nil { + return err + } + if p.DecodeOptions().DecodeStreamsAsDatagrams { + return p.NextDecoder(tcp.NextLayerType()) + } else { + return p.NextDecoder(gopacket.LayerTypePayload) + } +} + +func (t *TCP) TransportFlow() gopacket.Flow { + return gopacket.NewFlow(EndpointTCPPort, t.sPort, t.dPort) +} + +// For testing only +func (t *TCP) SetInternalPortsForTesting() { + t.sPort = make([]byte, 2) + t.dPort = make([]byte, 2) + binary.BigEndian.PutUint16(t.sPort, uint16(t.SrcPort)) + binary.BigEndian.PutUint16(t.dPort, uint16(t.DstPort)) +} diff --git a/vendor/github.com/google/gopacket/layers/tcp_test.go b/vendor/github.com/google/gopacket/layers/tcp_test.go new file mode 100644 index 0000000..56a6aaa --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/tcp_test.go @@ -0,0 +1,60 @@ +// Copyright 2016, Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "testing" + + "github.com/google/gopacket" +) + +func TestTCPOptionKindString(t *testing.T) { + testData := []struct { + o *TCPOption + s string + }{ + {&TCPOption{ + OptionType: TCPOptionKindNop, + OptionLength: 1, + }, + "TCPOption(NOP:)"}, + {&TCPOption{ + OptionType: TCPOptionKindMSS, + OptionLength: 4, + OptionData: []byte{0x12, 0x34}, + }, + "TCPOption(MSS:4660 0x1234)"}, + {&TCPOption{ + OptionType: TCPOptionKindTimestamps, + OptionLength: 10, + OptionData: []byte{0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01}, + }, + "TCPOption(Timestamps:2/1 0x0000000200000001)"}} + + for _, tc := range testData { + if s := tc.o.String(); s != tc.s { + t.Errorf("expected %#v string to be %s, got %s", tc.o, tc.s, s) + } + } +} + +func TestTCPSerializePadding(t *testing.T) { + tcp := &TCP{} + tcp.Options = append(tcp.Options, TCPOption{ + OptionType: TCPOptionKindNop, + OptionLength: 1, + }) + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{FixLengths: true} + err := gopacket.SerializeLayers(buf, opts, tcp) + if err != nil { + t.Fatal(err) + } + if len(buf.Bytes())%4 != 0 { + t.Errorf("TCP data of len %d not padding to 32 bit boundary", len(buf.Bytes())) + } +} diff --git a/vendor/github.com/google/gopacket/layers/tcpip.go b/vendor/github.com/google/gopacket/layers/tcpip.go new file mode 100644 index 0000000..64ba51c --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/tcpip.go @@ -0,0 +1,104 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// Copyright 2009-2011 Andreas Krennmair. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "errors" + "fmt" + + "github.com/google/gopacket" +) + +// Checksum computation for TCP/UDP. +type tcpipchecksum struct { + pseudoheader tcpipPseudoHeader +} + +type tcpipPseudoHeader interface { + pseudoheaderChecksum() (uint32, error) +} + +func (ip *IPv4) pseudoheaderChecksum() (csum uint32, err error) { + if err := ip.AddressTo4(); err != nil { + return 0, err + } + csum += (uint32(ip.SrcIP[0]) + uint32(ip.SrcIP[2])) << 8 + csum += uint32(ip.SrcIP[1]) + uint32(ip.SrcIP[3]) + csum += (uint32(ip.DstIP[0]) + uint32(ip.DstIP[2])) << 8 + csum += uint32(ip.DstIP[1]) + uint32(ip.DstIP[3]) + return csum, nil +} + +func (ip *IPv6) pseudoheaderChecksum() (csum uint32, err error) { + if err := ip.AddressTo16(); err != nil { + return 0, err + } + for i := 0; i < 16; i += 2 { + csum += uint32(ip.SrcIP[i]) << 8 + csum += uint32(ip.SrcIP[i+1]) + csum += uint32(ip.DstIP[i]) << 8 + csum += uint32(ip.DstIP[i+1]) + } + return csum, nil +} + +// Calculate the TCP/IP checksum defined in rfc1071. The passed-in csum is any +// initial checksum data that's already been computed. +func tcpipChecksum(data []byte, csum uint32) uint16 { + // to handle odd lengths, we loop to length - 1, incrementing by 2, then + // handle the last byte specifically by checking against the original + // length. + length := len(data) - 1 + for i := 0; i < length; i += 2 { + // For our test packet, doing this manually is about 25% faster + // (740 ns vs. 1000ns) than doing it by calling binary.BigEndian.Uint16. + csum += uint32(data[i]) << 8 + csum += uint32(data[i+1]) + } + if len(data)%2 == 1 { + csum += uint32(data[length]) << 8 + } + for csum > 0xffff { + csum = (csum >> 16) + (csum & 0xffff) + } + return ^uint16(csum) +} + +// computeChecksum computes a TCP or UDP checksum. headerAndPayload is the +// serialized TCP or UDP header plus its payload, with the checksum zero'd +// out. headerProtocol is the IP protocol number of the upper-layer header. +func (c *tcpipchecksum) computeChecksum(headerAndPayload []byte, headerProtocol IPProtocol) (uint16, error) { + if c.pseudoheader == nil { + return 0, errors.New("TCP/IP layer 4 checksum cannot be computed without network layer... call SetNetworkLayerForChecksum to set which layer to use") + } + length := uint32(len(headerAndPayload)) + csum, err := c.pseudoheader.pseudoheaderChecksum() + if err != nil { + return 0, err + } + csum += uint32(headerProtocol) + csum += length & 0xffff + csum += length >> 16 + return tcpipChecksum(headerAndPayload, csum), nil +} + +// SetNetworkLayerForChecksum tells this layer which network layer is wrapping it. +// This is needed for computing the checksum when serializing, since TCP/IP transport +// layer checksums depends on fields in the IPv4 or IPv6 layer that contains it. +// The passed in layer must be an *IPv4 or *IPv6. +func (i *tcpipchecksum) SetNetworkLayerForChecksum(l gopacket.NetworkLayer) error { + switch v := l.(type) { + case *IPv4: + i.pseudoheader = v + case *IPv6: + i.pseudoheader = v + default: + return fmt.Errorf("cannot use layer type %v for tcp checksum network layer", l.LayerType()) + } + return nil +} diff --git a/vendor/github.com/google/gopacket/layers/tcpip_test.go b/vendor/github.com/google/gopacket/layers/tcpip_test.go new file mode 100644 index 0000000..c002e84 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/tcpip_test.go @@ -0,0 +1,185 @@ +// Copyright 2014, Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "github.com/google/gopacket" + "net" + "testing" +) + +const ( + ipv4UDPChecksum = uint16(0xbc5f) // Wireshark + ipv6UDPChecksumWithIPv6DstOpts = uint16(0x4d21) // Wireshark + ipv6UDPChecksumJumbogram = uint16(0xcda8) +) + +func createIPv4ChecksumTestLayer() (ip4 *IPv4) { + ip4 = &IPv4{} + ip4.Version = 4 + ip4.TTL = 64 + ip4.SrcIP = net.ParseIP("192.0.2.1") + ip4.DstIP = net.ParseIP("198.51.100.1") + return +} + +func createIPv6ChecksumTestLayer() (ip6 *IPv6) { + ip6 = &IPv6{} + ip6.Version = 6 + ip6.NextHeader = IPProtocolNoNextHeader + ip6.HopLimit = 64 + ip6.SrcIP = net.ParseIP("2001:db8::1") + ip6.DstIP = net.ParseIP("2001:db8::2") + return +} + +func createIPv6DestinationChecksumTestLayer() (dst *IPv6Destination) { + tlv := &IPv6DestinationOption{} + tlv.OptionType = 0x01 //PadN + tlv.OptionData = []byte{0x00, 0x00, 0x00, 0x00} + dst = &IPv6Destination{} + dst.Options = append(dst.Options, tlv) + dst.NextHeader = IPProtocolNoNextHeader + return +} + +func createUDPChecksumTestLayer() (udp *UDP) { + udp = &UDP{} + udp.SrcPort = UDPPort(12345) + udp.DstPort = UDPPort(9999) + return +} + +func TestIPv4UDPChecksum(t *testing.T) { + var serialize []gopacket.SerializableLayer = make([]gopacket.SerializableLayer, 0, 2) + var u *UDP + var err error + + ip4 := createIPv4ChecksumTestLayer() + ip4.Protocol = IPProtocolUDP + serialize = append(serialize, ip4) + + udp := createUDPChecksumTestLayer() + udp.SetNetworkLayerForChecksum(ip4) + serialize = append(serialize, udp) + + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{FixLengths: true, ComputeChecksums: true} + err = gopacket.SerializeLayers(buf, opts, serialize...) + if err != nil { + t.Fatal(err) + } + + p := gopacket.NewPacket(buf.Bytes(), LinkTypeRaw, gopacket.Default) + if p.ErrorLayer() != nil { + t.Fatal("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeIPv4, LayerTypeUDP}, t) + + if l, ok := p.Layer(LayerTypeUDP).(*UDP); !ok { + t.Fatal("No UDP layer type found in packet") + } else { + u = l + } + got := u.Checksum + want := ipv4UDPChecksum + if got != want { + t.Errorf("Bad checksum:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want) + } +} + +func TestIPv6UDPChecksumWithIPv6DstOpts(t *testing.T) { + var serialize []gopacket.SerializableLayer = make([]gopacket.SerializableLayer, 0, 3) + var u *UDP + var err error + + ip6 := createIPv6ChecksumTestLayer() + ip6.NextHeader = IPProtocolIPv6Destination + serialize = append(serialize, ip6) + + dst := createIPv6DestinationChecksumTestLayer() + dst.NextHeader = IPProtocolUDP + serialize = append(serialize, dst) + + udp := createUDPChecksumTestLayer() + udp.SetNetworkLayerForChecksum(ip6) + serialize = append(serialize, udp) + + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{FixLengths: true, ComputeChecksums: true} + err = gopacket.SerializeLayers(buf, opts, serialize...) + if err != nil { + t.Fatal(err) + } + + p := gopacket.NewPacket(buf.Bytes(), LinkTypeRaw, gopacket.Default) + if p.ErrorLayer() != nil { + t.Fatal("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeIPv6, LayerTypeIPv6Destination, LayerTypeUDP}, t) + + if l, ok := p.Layer(LayerTypeUDP).(*UDP); !ok { + t.Fatal("No UDP layer type found in packet") + } else { + u = l + } + got := u.Checksum + want := ipv6UDPChecksumWithIPv6DstOpts + if got != want { + t.Errorf("Bad checksum:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want) + } +} + +func TestIPv6JumbogramUDPChecksum(t *testing.T) { + var serialize []gopacket.SerializableLayer = make([]gopacket.SerializableLayer, 0, 4) + var u *UDP + var err error + + ip6 := &IPv6{} + ip6.Version = 6 + ip6.NextHeader = IPProtocolUDP + ip6.HopLimit = 64 + ip6.SrcIP = net.ParseIP("2001:db8::1") + ip6.DstIP = net.ParseIP("2001:db8::2") + serialize = append(serialize, ip6) + + udp := &UDP{} + udp.SrcPort = UDPPort(12345) + udp.DstPort = UDPPort(9999) + udp.SetNetworkLayerForChecksum(ip6) + serialize = append(serialize, udp) + + payload := make([]byte, ipv6MaxPayloadLength+1) + for i := range payload { + payload[i] = 0xfe + } + serialize = append(serialize, gopacket.Payload(payload)) + + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{FixLengths: true, ComputeChecksums: true} + err = gopacket.SerializeLayers(buf, opts, serialize...) + if err != nil { + t.Fatal(err) + } + + p := gopacket.NewPacket(buf.Bytes(), LinkTypeRaw, gopacket.Default) + if p.ErrorLayer() != nil { + t.Fatal("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeIPv6, LayerTypeIPv6HopByHop, LayerTypeUDP, gopacket.LayerTypePayload}, t) + + if l, ok := p.Layer(LayerTypeUDP).(*UDP); !ok { + t.Fatal("No UDP layer type found in packet") + } else { + u = l + } + got := u.Checksum + want := ipv6UDPChecksumJumbogram + if got != want { + t.Errorf("Bad checksum:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want) + } +} diff --git a/vendor/github.com/google/gopacket/layers/test_creator.py b/vendor/github.com/google/gopacket/layers/test_creator.py new file mode 100755 index 0000000..c92d276 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/test_creator.py @@ -0,0 +1,103 @@ +#!/usr/bin/python +# Copyright 2012 Google, Inc. All rights reserved. + +"""TestCreator creates test templates from pcap files.""" + +import argparse +import base64 +import glob +import re +import string +import subprocess +import sys + + +class Packet(object): + """Helper class encapsulating packet from a pcap file.""" + + def __init__(self, packet_lines): + self.packet_lines = packet_lines + self.data = self._DecodeText(packet_lines) + + @classmethod + def _DecodeText(cls, packet_lines): + packet_bytes = [] + # First line is timestamp and stuff, skip it. + # Format: 0x0010: 0000 0020 3aff 3ffe 0000 0000 0000 0000 ....:.?......... + + for line in packet_lines[1:]: + m = re.match(r'\s+0x[a-f\d]+:\s+((?:[\da-f]{2,4}\s)*)', line, re.IGNORECASE) + if m is None: continue + for hexpart in m.group(1).split(): + packet_bytes.append(base64.b16decode(hexpart.upper())) + return ''.join(packet_bytes) + + def Test(self, name, link_type): + """Yields a test using this packet, as a set of lines.""" + yield '// testPacket%s is the packet:' % name + for line in self.packet_lines: + yield '// ' + line + yield 'var testPacket%s = []byte{' % name + data = list(self.data) + while data: + linebytes, data = data[:16], data[16:] + yield ''.join(['\t'] + ['0x%02x, ' % ord(c) for c in linebytes]) + yield '}' + yield 'func TestPacket%s(t *testing.T) {' % name + yield '\tp := gopacket.NewPacket(testPacket%s, LinkType%s, gopacket.Default)' % (name, link_type) + yield '\tif p.ErrorLayer() != nil {' + yield '\t\tt.Error("Failed to decode packet:", p.ErrorLayer().Error())' + yield '\t}' + yield '\tcheckLayers(p, []gopacket.LayerType{LayerType%s, FILL_ME_IN_WITH_ACTUAL_LAYERS}, t)' % link_type + yield '}' + yield 'func BenchmarkDecodePacket%s(b *testing.B) {' % name + yield '\tfor i := 0; i < b.N; i++ {' + yield '\t\tgopacket.NewPacket(testPacket%s, LinkType%s, gopacket.NoCopy)' % (name, link_type) + yield '\t}' + yield '}' + + + +def GetTcpdumpOutput(filename): + """Runs tcpdump on the given file, returning output as string.""" + return subprocess.check_output( + ['tcpdump', '-XX', '-s', '0', '-n', '-r', filename]) + + +def TcpdumpOutputToPackets(output): + """Reads a pcap file with TCPDump, yielding Packet objects.""" + pdata = [] + for line in output.splitlines(): + if line[0] not in string.whitespace and pdata: + yield Packet(pdata) + pdata = [] + pdata.append(line) + if pdata: + yield Packet(pdata) + + +def main(): + class CustomHelpFormatter(argparse.ArgumentDefaultsHelpFormatter): + def _format_usage(self, usage, actions, groups, prefix=None): + header =('TestCreator creates gopacket tests using a pcap file.\n\n' + 'Tests are written to standard out... they can then be \n' + 'copied into the file of your choice and modified as \n' + 'you see.\n\n') + return header + argparse.ArgumentDefaultsHelpFormatter._format_usage( + self, usage, actions, groups, prefix) + + parser = argparse.ArgumentParser(formatter_class=CustomHelpFormatter) + parser.add_argument('--link_type', default='Ethernet', help='the link type (default: %(default)s)') + parser.add_argument('--name', default='Packet%d', help='the layer type, must have "%d" inside it') + parser.add_argument('files', metavar='file.pcap', type=str, nargs='+', help='the files to process') + + args = parser.parse_args() + + for arg in args.files: + for path in glob.glob(arg): + for i, packet in enumerate(TcpdumpOutputToPackets(GetTcpdumpOutput(path))): + print '\n'.join(packet.Test( + args.name % i, args.link_type)) + +if __name__ == '__main__': + main() diff --git a/vendor/github.com/google/gopacket/layers/udp.go b/vendor/github.com/google/gopacket/layers/udp.go new file mode 100644 index 0000000..20f8c50 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/udp.go @@ -0,0 +1,120 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// Copyright 2009-2011 Andreas Krennmair. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "fmt" + "github.com/google/gopacket" +) + +// UDP is the layer for UDP headers. +type UDP struct { + BaseLayer + SrcPort, DstPort UDPPort + Length uint16 + Checksum uint16 + sPort, dPort []byte + tcpipchecksum +} + +// LayerType returns gopacket.LayerTypeUDP +func (u *UDP) LayerType() gopacket.LayerType { return LayerTypeUDP } + +func (udp *UDP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + udp.SrcPort = UDPPort(binary.BigEndian.Uint16(data[0:2])) + udp.sPort = data[0:2] + udp.DstPort = UDPPort(binary.BigEndian.Uint16(data[2:4])) + udp.dPort = data[2:4] + udp.Length = binary.BigEndian.Uint16(data[4:6]) + udp.Checksum = binary.BigEndian.Uint16(data[6:8]) + udp.BaseLayer = BaseLayer{Contents: data[:8]} + switch { + case udp.Length >= 8: + hlen := int(udp.Length) + if hlen > len(data) { + df.SetTruncated() + hlen = len(data) + } + udp.Payload = data[8:hlen] + case udp.Length == 0: // Jumbogram, use entire rest of data + udp.Payload = data[8:] + default: + return fmt.Errorf("UDP packet too small: %d bytes", udp.Length) + } + return nil +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (u *UDP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + var jumbo bool + + payload := b.Bytes() + if _, ok := u.pseudoheader.(*IPv6); ok { + if len(payload)+8 > 65535 { + jumbo = true + } + } + bytes, err := b.PrependBytes(8) + if err != nil { + return err + } + binary.BigEndian.PutUint16(bytes, uint16(u.SrcPort)) + binary.BigEndian.PutUint16(bytes[2:], uint16(u.DstPort)) + if opts.FixLengths { + if jumbo { + u.Length = 0 + } else { + u.Length = uint16(len(payload)) + 8 + } + } + binary.BigEndian.PutUint16(bytes[4:], u.Length) + if opts.ComputeChecksums { + // zero out checksum bytes + bytes[6] = 0 + bytes[7] = 0 + csum, err := u.computeChecksum(b.Bytes(), IPProtocolUDP) + if err != nil { + return err + } + u.Checksum = csum + } + binary.BigEndian.PutUint16(bytes[6:], u.Checksum) + return nil +} + +func (u *UDP) CanDecode() gopacket.LayerClass { + return LayerTypeUDP +} + +// NextLayerType use the destination port to select the +// right next decoder. It tries first to decode via the +// destination port, then the source port. +func (u *UDP) NextLayerType() gopacket.LayerType { + if lt := u.DstPort.LayerType(); lt != gopacket.LayerTypePayload { + return lt + } + return u.SrcPort.LayerType() +} + +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(udp.NextLayerType()) +} + +func (u *UDP) TransportFlow() gopacket.Flow { + return gopacket.NewFlow(EndpointUDPPort, u.sPort, u.dPort) +} diff --git a/vendor/github.com/google/gopacket/layers/udp_test.go b/vendor/github.com/google/gopacket/layers/udp_test.go new file mode 100644 index 0000000..e71236c --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/udp_test.go @@ -0,0 +1,372 @@ +// Copyright 2012, Google, Inc. All rights reserved. +// Copyright 2009-2011 Andreas Krennmair. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "reflect" + "testing" + + "github.com/google/gopacket" +) + +// testUDPPacketDNS is the packet: +// 10:33:07.883637 IP 172.16.255.1.53 > 172.29.20.15.35181: 47320 7/0/0 MX ALT2.ASPMX.L.GOOGLE.com. 20, MX ASPMX2.GOOGLEMAIL.com. 30, MX ASPMX3.GOOGLEMAIL.com. 30, MX ASPMX4.GOOGLEMAIL.com. 30, MX ASPMX5.GOOGLEMAIL.com. 30, MX ASPMX.L.GOOGLE.com. 10, MX ALT1.ASPMX.L.GOOGLE.com. 20 (202) +// 0x0000: 24be 0527 0b17 001f cab3 75c0 0800 4500 $..'......u...E. +// 0x0010: 00e6 68cf 0000 3f11 a6f9 ac10 ff01 ac1d ..h...?......... +// 0x0020: 140f 0035 896d 00d2 754a b8d8 8180 0001 ...5.m..uJ...... +// 0x0030: 0007 0000 0000 0478 6b63 6403 636f 6d00 .......xkcd.com. +// 0x0040: 000f 0001 c00c 000f 0001 0000 0258 0018 .............X.. +// 0x0050: 0014 0441 4c54 3205 4153 504d 5801 4c06 ...ALT2.ASPMX.L. +// 0x0060: 474f 4f47 4c45 c011 c00c 000f 0001 0000 GOOGLE.......... +// 0x0070: 0258 0016 001e 0641 5350 4d58 320a 474f .X.....ASPMX2.GO +// 0x0080: 4f47 4c45 4d41 494c c011 c00c 000f 0001 OGLEMAIL........ +// 0x0090: 0000 0258 000b 001e 0641 5350 4d58 33c0 ...X.....ASPMX3. +// 0x00a0: 53c0 0c00 0f00 0100 0002 5800 0b00 1e06 S.........X..... +// 0x00b0: 4153 504d 5834 c053 c00c 000f 0001 0000 ASPMX4.S........ +// 0x00c0: 0258 000b 001e 0641 5350 4d58 35c0 53c0 .X.....ASPMX5.S. +// 0x00d0: 0c00 0f00 0100 0002 5800 0400 0ac0 2dc0 ........X.....-. +// 0x00e0: 0c00 0f00 0100 0002 5800 0900 1404 414c ........X.....AL +// 0x00f0: 5431 c02d T1.- +// Packet generated by doing DNS query for 'xkcd.com' +var testUDPPacketDNS = []byte{ + 0x24, 0xbe, 0x05, 0x27, 0x0b, 0x17, 0x00, 0x1f, 0xca, 0xb3, 0x75, 0xc0, 0x08, 0x00, 0x45, 0x00, + 0x00, 0xe6, 0x68, 0xcf, 0x00, 0x00, 0x3f, 0x11, 0xa6, 0xf9, 0xac, 0x10, 0xff, 0x01, 0xac, 0x1d, + 0x14, 0x0f, 0x00, 0x35, 0x89, 0x6d, 0x00, 0xd2, 0x75, 0x4a, 0xb8, 0xd8, 0x81, 0x80, 0x00, 0x01, + 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x04, 0x78, 0x6b, 0x63, 0x64, 0x03, 0x63, 0x6f, 0x6d, 0x00, + 0x00, 0x0f, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x00, 0x02, 0x58, 0x00, 0x18, + 0x00, 0x14, 0x04, 0x41, 0x4c, 0x54, 0x32, 0x05, 0x41, 0x53, 0x50, 0x4d, 0x58, 0x01, 0x4c, 0x06, + 0x47, 0x4f, 0x4f, 0x47, 0x4c, 0x45, 0xc0, 0x11, 0xc0, 0x0c, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x00, + 0x02, 0x58, 0x00, 0x16, 0x00, 0x1e, 0x06, 0x41, 0x53, 0x50, 0x4d, 0x58, 0x32, 0x0a, 0x47, 0x4f, + 0x4f, 0x47, 0x4c, 0x45, 0x4d, 0x41, 0x49, 0x4c, 0xc0, 0x11, 0xc0, 0x0c, 0x00, 0x0f, 0x00, 0x01, + 0x00, 0x00, 0x02, 0x58, 0x00, 0x0b, 0x00, 0x1e, 0x06, 0x41, 0x53, 0x50, 0x4d, 0x58, 0x33, 0xc0, + 0x53, 0xc0, 0x0c, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x00, 0x02, 0x58, 0x00, 0x0b, 0x00, 0x1e, 0x06, + 0x41, 0x53, 0x50, 0x4d, 0x58, 0x34, 0xc0, 0x53, 0xc0, 0x0c, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x00, + 0x02, 0x58, 0x00, 0x0b, 0x00, 0x1e, 0x06, 0x41, 0x53, 0x50, 0x4d, 0x58, 0x35, 0xc0, 0x53, 0xc0, + 0x0c, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x00, 0x02, 0x58, 0x00, 0x04, 0x00, 0x0a, 0xc0, 0x2d, 0xc0, + 0x0c, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x00, 0x02, 0x58, 0x00, 0x09, 0x00, 0x14, 0x04, 0x41, 0x4c, + 0x54, 0x31, 0xc0, 0x2d, +} + +func TestUDPPacketDNS(t *testing.T) { + p := gopacket.NewPacket(testUDPPacketDNS, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeUDP, LayerTypeDNS}, t) + if got, ok := p.TransportLayer().(*UDP); ok { + want := &UDP{ + BaseLayer: BaseLayer{ + Contents: []byte{0x0, 0x35, 0x89, 0x6d, 0x0, 0xd2, 0x75, 0x4a}, + Payload: []byte{0xb8, 0xd8, 0x81, 0x80, 0x0, 0x1, 0x0, + 0x7, 0x0, 0x0, 0x0, 0x0, 0x4, 0x78, 0x6b, 0x63, 0x64, 0x3, 0x63, 0x6f, + 0x6d, 0x0, 0x0, 0xf, 0x0, 0x1, 0xc0, 0xc, 0x0, 0xf, 0x0, 0x1, 0x0, 0x0, + 0x2, 0x58, 0x0, 0x18, 0x0, 0x14, 0x4, 0x41, 0x4c, 0x54, 0x32, 0x5, 0x41, + 0x53, 0x50, 0x4d, 0x58, 0x1, 0x4c, 0x6, 0x47, 0x4f, 0x4f, 0x47, 0x4c, + 0x45, 0xc0, 0x11, 0xc0, 0xc, 0x0, 0xf, 0x0, 0x1, 0x0, 0x0, 0x2, 0x58, 0x0, + 0x16, 0x0, 0x1e, 0x6, 0x41, 0x53, 0x50, 0x4d, 0x58, 0x32, 0xa, 0x47, 0x4f, + 0x4f, 0x47, 0x4c, 0x45, 0x4d, 0x41, 0x49, 0x4c, 0xc0, 0x11, 0xc0, 0xc, + 0x0, 0xf, 0x0, 0x1, 0x0, 0x0, 0x2, 0x58, 0x0, 0xb, 0x0, 0x1e, 0x6, 0x41, + 0x53, 0x50, 0x4d, 0x58, 0x33, 0xc0, 0x53, 0xc0, 0xc, 0x0, 0xf, 0x0, 0x1, + 0x0, 0x0, 0x2, 0x58, 0x0, 0xb, 0x0, 0x1e, 0x6, 0x41, 0x53, 0x50, 0x4d, + 0x58, 0x34, 0xc0, 0x53, 0xc0, 0xc, 0x0, 0xf, 0x0, 0x1, 0x0, 0x0, 0x2, + 0x58, 0x0, 0xb, 0x0, 0x1e, 0x6, 0x41, 0x53, 0x50, 0x4d, 0x58, 0x35, 0xc0, + 0x53, 0xc0, 0xc, 0x0, 0xf, 0x0, 0x1, 0x0, 0x0, 0x2, 0x58, 0x0, 0x4, 0x0, + 0xa, 0xc0, 0x2d, 0xc0, 0xc, 0x0, 0xf, 0x0, 0x1, 0x0, 0x0, 0x2, 0x58, 0x0, + 0x9, 0x0, 0x14, 0x4, 0x41, 0x4c, 0x54, 0x31, 0xc0, 0x2d}, + }, + SrcPort: 53, + DstPort: 35181, + Length: 210, + Checksum: 30026, + sPort: []byte{0x0, 0x35}, + dPort: []byte{0x89, 0x6d}, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("UDP packet mismatch:\ngot :\n%#v\n\nwant :\n%#v\n\n", got, want) + } + } else { + t.Error("Transport layer packet not UDP") + } +} + +func loadDNS(dnspacket []byte, t *testing.T) *DNS { + p := gopacket.NewPacket(dnspacket, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, + LayerTypeUDP, LayerTypeDNS}, t) + + dnsL := p.Layer(LayerTypeDNS) + if dnsL == nil { + t.Error("No DNS Layer found") + } + + dns, ok := dnsL.(*DNS) + if !ok { + return nil + } + return dns +} + +var testDNSQueryA = []byte{ + 0xfe, 0x54, 0x00, 0x3e, 0x00, 0x96, 0x52, 0x54, /* .T.>..RT */ + 0x00, 0xbd, 0x1c, 0x70, 0x08, 0x00, 0x45, 0x00, /* ...p..E. */ + 0x00, 0x3c, 0x22, 0xe0, 0x00, 0x00, 0x40, 0x11, /* .<"...@. */ + 0xe2, 0x38, 0xc0, 0xa8, 0x7a, 0x46, 0xc0, 0xa8, /* .8..zF.. */ + 0x7a, 0x01, 0xc3, 0x35, 0x00, 0x35, 0x00, 0x28, /* z..5.5.( */ + 0x75, 0xd2, 0x52, 0x41, 0x01, 0x00, 0x00, 0x01, /* u.RA.... */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, /* .......w */ + 0x77, 0x77, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, /* ww.googl */ + 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, /* e.com... */ + 0x00, 0x01, /* .. */ +} + +func TestDNSQueryA(t *testing.T) { + dns := loadDNS(testDNSQueryA, t) + if dns == nil { + t.Fatal("Failed to get a pointer to DNS struct") + } + + if uint16(len(dns.Questions)) != dns.QDCount { + t.Fatal("Invalid query decoding, not the right number of questions") + } + + if string(dns.Questions[0].Name) != "www.google.com" { + t.Errorf("Invalid query decoding, expecting 'www.google.com', got '%s'", + dns.Questions[0].Name) + } + if dns.Questions[0].Class != DNSClassIN { + t.Errorf("Invalid query decoding, expecting Class IN, got '%d'", + dns.Questions[0].Class) + } + + if dns.Questions[0].Type != DNSTypeA { + t.Errorf("Invalid query decoding, expecting Type A, got '%d'", + dns.Questions[0].Type) + } +} + +var testDNSRRA = []byte{ + 0x52, 0x54, 0x00, 0xbd, 0x1c, 0x70, 0xfe, 0x54, /* RT...p.T */ + 0x00, 0x3e, 0x00, 0x96, 0x08, 0x00, 0x45, 0x00, /* .>....E. */ + 0x01, 0x24, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, /* .$..@.@. */ + 0xc4, 0x30, 0xc0, 0xa8, 0x7a, 0x01, 0xc0, 0xa8, /* .0..z... */ + 0x7a, 0x46, 0x00, 0x35, 0xc3, 0x35, 0x01, 0x10, /* zF.5.5.. */ + 0x76, 0xba, 0x52, 0x41, 0x81, 0x80, 0x00, 0x01, /* v.RA.... */ + 0x00, 0x06, 0x00, 0x04, 0x00, 0x04, 0x03, 0x77, /* .......w */ + 0x77, 0x77, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, /* ww.googl */ + 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, /* e.com... */ + 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, /* ........ */ + 0x00, 0x00, 0x01, 0x2c, 0x00, 0x04, 0x4a, 0x7d, /* ...,..J} */ + 0xc3, 0x67, 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, /* .g...... */ + 0x00, 0x00, 0x01, 0x2c, 0x00, 0x04, 0x4a, 0x7d, /* ...,..J} */ + 0xc3, 0x68, 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, /* .h...... */ + 0x00, 0x00, 0x01, 0x2c, 0x00, 0x04, 0x4a, 0x7d, /* ...,..J} */ + 0xc3, 0x69, 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, /* .i...... */ + 0x00, 0x00, 0x01, 0x2c, 0x00, 0x04, 0x4a, 0x7d, /* ...,..J} */ + 0xc3, 0x6a, 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, /* .j...... */ + 0x00, 0x00, 0x01, 0x2c, 0x00, 0x04, 0x4a, 0x7d, /* ...,..J} */ + 0xc3, 0x93, 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, /* ........ */ + 0x00, 0x00, 0x01, 0x2c, 0x00, 0x04, 0x4a, 0x7d, /* ...,..J} */ + 0xc3, 0x63, 0xc0, 0x10, 0x00, 0x02, 0x00, 0x01, /* .c...... */ + 0x00, 0x02, 0xa3, 0x00, 0x00, 0x06, 0x03, 0x6e, /* .......n */ + 0x73, 0x32, 0xc0, 0x10, 0xc0, 0x10, 0x00, 0x02, /* s2...... */ + 0x00, 0x01, 0x00, 0x02, 0xa3, 0x00, 0x00, 0x06, /* ........ */ + 0x03, 0x6e, 0x73, 0x33, 0xc0, 0x10, 0xc0, 0x10, /* .ns3.... */ + 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0xa3, 0x00, /* ........ */ + 0x00, 0x06, 0x03, 0x6e, 0x73, 0x31, 0xc0, 0x10, /* ...ns1.. */ + 0xc0, 0x10, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, /* ........ */ + 0xa3, 0x00, 0x00, 0x06, 0x03, 0x6e, 0x73, 0x34, /* .....ns4 */ + 0xc0, 0x10, 0xc0, 0xb0, 0x00, 0x01, 0x00, 0x01, /* ........ */ + 0x00, 0x02, 0xa3, 0x00, 0x00, 0x04, 0xd8, 0xef, /* ........ */ + 0x20, 0x0a, 0xc0, 0x8c, 0x00, 0x01, 0x00, 0x01, /* ....... */ + 0x00, 0x02, 0xa3, 0x00, 0x00, 0x04, 0xd8, 0xef, /* ........ */ + 0x22, 0x0a, 0xc0, 0x9e, 0x00, 0x01, 0x00, 0x01, /* "....... */ + 0x00, 0x02, 0xa3, 0x00, 0x00, 0x04, 0xd8, 0xef, /* ........ */ + 0x24, 0x0a, 0xc0, 0xc2, 0x00, 0x01, 0x00, 0x01, /* $....... */ + 0x00, 0x02, 0xa3, 0x00, 0x00, 0x04, 0xd8, 0xef, /* ........ */ + 0x26, 0x0a, /* &. */ +} + +func TestDNSRRA(t *testing.T) { + dns := loadDNS(testDNSRRA, t) + if dns == nil { + t.Fatal("Failed to get a pointer to DNS struct") + return + } + + if uint16(len(dns.Questions)) != dns.QDCount { + t.Fatal("Invalid query decoding, not the right number of questions") + } else if uint16(len(dns.Answers)) != dns.ANCount { + t.Fatal("Invalid query decoding, not the right number of answers") + } else if uint16(len(dns.Authorities)) != dns.NSCount { + t.Fatal("Invalid query decoding, not the right number of authorities") + } else if uint16(len(dns.Additionals)) != dns.ARCount { + t.Fatal("Invalid query decoding, not the right number of additionals info") + } + + if string(dns.Questions[0].Name) != "www.google.com" { + t.Errorf("Invalid query decoding, expecting 'www.google.com', got '%s'", + dns.Questions[0].Name) + } + if string(dns.Answers[0].Name) != "www.google.com" { + t.Errorf("Invalid query decoding, expecting 'www.google.com', got '%d'", + dns.Questions[0].Class) + } + if dns.Answers[0].Class != DNSClassIN { + t.Errorf("Invalid query decoding, expecting Class IN, got '%d'", + dns.Questions[0].Class) + } + if dns.Answers[0].Type != DNSTypeA { + t.Errorf("Invalid query decoding, expecting Type A, got '%d'", + dns.Questions[0].Type) + } + if !dns.Answers[0].IP.Equal([]byte{74, 125, 195, 103}) { + t.Errorf("Invalid query decoding, invalid IP address,"+ + " expecting '74.125.195.103', got '%s'", + dns.Answers[0].IP.String()) + } + if len(dns.Answers) != 6 { + t.Errorf("No correct number of answers, expecting 6, go '%d'", + len(dns.Answers)) + } + if len(dns.Authorities) != 4 { + t.Errorf("No correct number of answers, expecting 4, go '%d'", + len(dns.Answers)) + } + if len(dns.Additionals) != 4 { + t.Errorf("No correct number of answers, expecting 4, go '%d'", + len(dns.Answers)) + } else { + for i, want := range []string{ + "ns1.google.com", + "ns2.google.com", + "ns3.google.com", + "ns4.google.com", + } { + if got := string(dns.Additionals[i].Name); got != want { + t.Errorf("got %q want %q", got, want) + } + } + } +} + +var testDNSAAAA = []byte{ + 0x52, 0x54, 0x00, 0xbd, 0x1c, 0x70, 0xfe, 0x54, /* RT...p.T */ + 0x00, 0x3e, 0x00, 0x96, 0x08, 0x00, 0x45, 0x00, /* .>....E. */ + 0x00, 0xe0, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, /* ....@.@. */ + 0xc4, 0x74, 0xc0, 0xa8, 0x7a, 0x01, 0xc0, 0xa8, /* .t..z... */ + 0x7a, 0x46, 0x00, 0x35, 0xdb, 0x13, 0x00, 0xcc, /* zF.5.... */ + 0x76, 0x76, 0xf3, 0x03, 0x81, 0x80, 0x00, 0x01, /* vv...... */ + 0x00, 0x01, 0x00, 0x04, 0x00, 0x04, 0x03, 0x77, /* .......w */ + 0x77, 0x77, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, /* ww.googl */ + 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x1c, /* e.com... */ + 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x1c, 0x00, 0x01, /* ........ */ + 0x00, 0x00, 0x01, 0x2c, 0x00, 0x10, 0x2a, 0x00, /* ...,..*. */ + 0x14, 0x50, 0x40, 0x0c, 0x0c, 0x01, 0x00, 0x00, /* .P@..... */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xc0, 0x10, /* .....i.. */ + 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0xa3, 0x00, /* ........ */ + 0x00, 0x06, 0x03, 0x6e, 0x73, 0x34, 0xc0, 0x10, /* ...ns4.. */ + 0xc0, 0x10, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, /* ........ */ + 0xa3, 0x00, 0x00, 0x06, 0x03, 0x6e, 0x73, 0x32, /* .....ns2 */ + 0xc0, 0x10, 0xc0, 0x10, 0x00, 0x02, 0x00, 0x01, /* ........ */ + 0x00, 0x02, 0xa3, 0x00, 0x00, 0x06, 0x03, 0x6e, /* .......n */ + 0x73, 0x31, 0xc0, 0x10, 0xc0, 0x10, 0x00, 0x02, /* s1...... */ + 0x00, 0x01, 0x00, 0x02, 0xa3, 0x00, 0x00, 0x06, /* ........ */ + 0x03, 0x6e, 0x73, 0x33, 0xc0, 0x10, 0xc0, 0x6c, /* .ns3...l */ + 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0xa3, 0x00, /* ........ */ + 0x00, 0x04, 0xd8, 0xef, 0x20, 0x0a, 0xc0, 0x5a, /* .... ..Z */ + 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0xa3, 0x00, /* ........ */ + 0x00, 0x04, 0xd8, 0xef, 0x22, 0x0a, 0xc0, 0x7e, /* ...."..~ */ + 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0xa3, 0x00, /* ........ */ + 0x00, 0x04, 0xd8, 0xef, 0x24, 0x0a, 0xc0, 0x48, /* ....$..H */ + 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0xa3, 0x00, /* ........ */ + 0x00, 0x04, 0xd8, 0xef, 0x26, 0x0a, /* ....&. */ +} + +func TestDNSAAAA(t *testing.T) { + dns := loadDNS(testDNSAAAA, t) + if dns == nil { + t.Error("Failed to get a pointer to DNS struct") + return + } + + if len(dns.Questions) != 1 { + t.Error("Invalid number of question") + return + } + if dns.Questions[0].Type != DNSTypeAAAA { + t.Errorf("Invalid question, Type is not AAAA, found %d", + dns.Questions[0].Type) + } + + if len(dns.Answers) != 1 { + t.Error("Invalid number of answers") + } + if !dns.Answers[0].IP.Equal([]byte{0x2a, 0x00, 0x14, 0x50, 0x40, + 0x0c, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69}) { + t.Error("Invalid IP address, found ", + dns.Answers[0].IP.String()) + } +} + +var testDNSMXSOA = []byte{ + 0x52, 0x54, 0x00, 0xbd, 0x1c, 0x70, 0xfe, 0x54, /* RT...p.T */ + 0x00, 0x3e, 0x00, 0x96, 0x08, 0x00, 0x45, 0x00, /* .>....E. */ + 0x00, 0x6e, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, /* .n..@.@. */ + 0xc4, 0xe6, 0xc0, 0xa8, 0x7a, 0x01, 0xc0, 0xa8, /* ....z... */ + 0x7a, 0x46, 0x00, 0x35, 0x9c, 0x60, 0x00, 0x5a, /* zF.5.`.Z */ + 0x76, 0x04, 0xfc, 0x7a, 0x81, 0x80, 0x00, 0x01, /* v..z.... */ + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x77, /* .......w */ + 0x77, 0x77, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, /* ww.googl */ + 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x0f, /* e.com... */ + 0x00, 0x01, 0xc0, 0x10, 0x00, 0x06, 0x00, 0x01, /* ........ */ + 0x00, 0x00, 0x00, 0x3c, 0x00, 0x26, 0x03, 0x6e, /* ...<.&.n */ + 0x73, 0x31, 0xc0, 0x10, 0x09, 0x64, 0x6e, 0x73, /* s1...dns */ + 0x2d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0xc0, 0x10, /* -admin.. */ + 0x00, 0x17, 0x9f, 0x64, 0x00, 0x00, 0x1c, 0x20, /* ...d... */ + 0x00, 0x00, 0x07, 0x08, 0x00, 0x12, 0x75, 0x00, /* ......u. */ + 0x00, 0x00, 0x01, 0x2c, /* ..., */ +} + +func TestDNSMXSOA(t *testing.T) { + dns := loadDNS(testDNSMXSOA, t) + if dns == nil { + t.Error("Failed to get a pointer to DNS struct") + return + } + + if len(dns.Authorities) != 1 { + t.Error("Invalid number of authoritative answers, found ", + len(dns.Authorities)) + return + } +} + +func BenchmarkDecodeDNS(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testDNSQueryA, LinkTypeEthernet, gopacket.NoCopy) + } +} +func BenchmarkDecodeDNSLayer(b *testing.B) { + var dns DNS + for i := 0; i < b.N; i++ { + dns.DecodeFromBytes(testDNSAAAA[ /*eth*/ 14+ /*ipv4*/ 20+ /*udp*/ 8:], gopacket.NilDecodeFeedback) + } +} +func TestDNSDoesNotMalloc(t *testing.T) { + var dns DNS + if n := testing.AllocsPerRun(1000, func() { + if err := dns.DecodeFromBytes(testDNSAAAA[ /*eth*/ 14+ /*ipv4*/ 20+ /*udp*/ 8:], gopacket.NilDecodeFeedback); err != nil { + t.Fatal(err) + } + }); n > 0 { + t.Error(n, "mallocs decoding DNS") + } +} diff --git a/vendor/github.com/google/gopacket/layers/udplite.go b/vendor/github.com/google/gopacket/layers/udplite.go new file mode 100644 index 0000000..7d84c51 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/udplite.go @@ -0,0 +1,44 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// Copyright 2009-2011 Andreas Krennmair. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "github.com/google/gopacket" +) + +// UDPLite is the layer for UDP-Lite headers (rfc 3828). +type UDPLite struct { + BaseLayer + SrcPort, DstPort UDPLitePort + ChecksumCoverage uint16 + Checksum uint16 + sPort, dPort []byte +} + +// LayerType returns gopacket.LayerTypeUDPLite +func (u *UDPLite) LayerType() gopacket.LayerType { return LayerTypeUDPLite } + +func decodeUDPLite(data []byte, p gopacket.PacketBuilder) error { + udp := &UDPLite{ + SrcPort: UDPLitePort(binary.BigEndian.Uint16(data[0:2])), + sPort: data[0:2], + DstPort: UDPLitePort(binary.BigEndian.Uint16(data[2:4])), + dPort: data[2:4], + ChecksumCoverage: binary.BigEndian.Uint16(data[4:6]), + Checksum: binary.BigEndian.Uint16(data[6:8]), + BaseLayer: BaseLayer{data[:8], data[8:]}, + } + p.AddLayer(udp) + p.SetTransportLayer(udp) + return p.NextDecoder(gopacket.LayerTypePayload) +} + +func (u *UDPLite) TransportFlow() gopacket.Flow { + return gopacket.NewFlow(EndpointUDPLitePort, u.sPort, u.dPort) +} diff --git a/vendor/github.com/google/gopacket/layers/usb.go b/vendor/github.com/google/gopacket/layers/usb.go new file mode 100644 index 0000000..d4f483c --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/usb.go @@ -0,0 +1,308 @@ +// Copyright 2014 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "github.com/google/gopacket" +) + +type USBEventType uint8 + +const ( + USBEventTypeSubmit USBEventType = 'S' + USBEventTypeComplete USBEventType = 'C' + USBEventTypeError USBEventType = 'E' +) + +func (a USBEventType) String() string { + switch a { + case USBEventTypeSubmit: + return "SUBMIT" + case USBEventTypeComplete: + return "COMPLETE" + case USBEventTypeError: + return "ERROR" + default: + return "Unknown event type" + } +} + +type USBRequestBlockSetupRequest uint8 + +const ( + USBRequestBlockSetupRequestGetStatus USBRequestBlockSetupRequest = 0x00 + USBRequestBlockSetupRequestClearFeature USBRequestBlockSetupRequest = 0x01 + USBRequestBlockSetupRequestSetFeature USBRequestBlockSetupRequest = 0x03 + USBRequestBlockSetupRequestSetAddress USBRequestBlockSetupRequest = 0x05 + USBRequestBlockSetupRequestGetDescriptor USBRequestBlockSetupRequest = 0x06 + USBRequestBlockSetupRequestSetDescriptor USBRequestBlockSetupRequest = 0x07 + USBRequestBlockSetupRequestGetConfiguration USBRequestBlockSetupRequest = 0x08 + USBRequestBlockSetupRequestSetConfiguration USBRequestBlockSetupRequest = 0x09 + USBRequestBlockSetupRequestSetIdle USBRequestBlockSetupRequest = 0x0a +) + +func (a USBRequestBlockSetupRequest) String() string { + switch a { + case USBRequestBlockSetupRequestGetStatus: + return "GET_STATUS" + case USBRequestBlockSetupRequestClearFeature: + return "CLEAR_FEATURE" + case USBRequestBlockSetupRequestSetFeature: + return "SET_FEATURE" + case USBRequestBlockSetupRequestSetAddress: + return "SET_ADDRESS" + case USBRequestBlockSetupRequestGetDescriptor: + return "GET_DESCRIPTOR" + case USBRequestBlockSetupRequestSetDescriptor: + return "SET_DESCRIPTOR" + case USBRequestBlockSetupRequestGetConfiguration: + return "GET_CONFIGURATION" + case USBRequestBlockSetupRequestSetConfiguration: + return "SET_CONFIGURATION" + case USBRequestBlockSetupRequestSetIdle: + return "SET_IDLE" + default: + return "UNKNOWN" + } +} + +type USBTransportType uint8 + +const ( + USBTransportTypeTransferIn USBTransportType = 0x80 // Indicates send or receive + USBTransportTypeIsochronous USBTransportType = 0x00 // Isochronous transfers occur continuously and periodically. They typically contain time sensitive information, such as an audio or video stream. + USBTransportTypeInterrupt USBTransportType = 0x01 // Interrupt transfers are typically non-periodic, small device "initiated" communication requiring bounded latency, such as pointing devices or keyboards. + USBTransportTypeControl USBTransportType = 0x02 // Control transfers are typically used for command and status operations. + USBTransportTypeBulk USBTransportType = 0x03 // Bulk transfers can be used for large bursty data, using all remaining available bandwidth, no guarantees on bandwidth or latency, such as file transfers. +) + +func (a USBTransportType) LayerType() gopacket.LayerType { + return USBTypeMetadata[a].LayerType +} + +func (a USBTransportType) String() string { + switch a { + case USBTransportTypeTransferIn: + return "Transfer In" + case USBTransportTypeIsochronous: + return "Isochronous" + case USBTransportTypeInterrupt: + return "Interrupt" + case USBTransportTypeControl: + return "Control" + case USBTransportTypeBulk: + return "Bulk" + default: + return "Unknown transport type" + } +} + +type USBDirectionType uint8 + +const ( + USBDirectionTypeUnknown USBDirectionType = iota + USBDirectionTypeIn + USBDirectionTypeOut +) + +func (a USBDirectionType) String() string { + switch a { + case USBDirectionTypeIn: + return "In" + case USBDirectionTypeOut: + return "Out" + default: + return "Unknown direction type" + } +} + +// The reference at http://www.beyondlogic.org/usbnutshell/usb1.shtml contains more information about the protocol. +type USB struct { + BaseLayer + ID uint64 + EventType USBEventType + TransferType USBTransportType + Direction USBDirectionType + EndpointNumber uint8 + DeviceAddress uint8 + BusID uint16 + TimestampSec int64 + TimestampUsec int32 + Setup bool + Data bool + Status int32 + UrbLength uint32 + UrbDataLength uint32 + + UrbInterval uint32 + UrbStartFrame uint32 + UrbCopyOfTransferFlags uint32 + IsoNumDesc uint32 +} + +func (u *USB) LayerType() gopacket.LayerType { return LayerTypeUSB } + +func (m *USB) NextLayerType() gopacket.LayerType { + if m.Setup { + return LayerTypeUSBRequestBlockSetup + } else if m.Data { + } + + return m.TransferType.LayerType() +} + +func decodeUSB(data []byte, p gopacket.PacketBuilder) error { + d := &USB{} + + return decodingLayerDecoder(d, data, p) +} + +func (m *USB) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + m.ID = binary.LittleEndian.Uint64(data[0:8]) + m.EventType = USBEventType(data[8]) + m.TransferType = USBTransportType(data[9]) + + m.EndpointNumber = data[10] & 0x7f + if data[10]&uint8(USBTransportTypeTransferIn) > 0 { + m.Direction = USBDirectionTypeIn + } else { + m.Direction = USBDirectionTypeOut + } + + m.DeviceAddress = data[11] + m.BusID = binary.LittleEndian.Uint16(data[12:14]) + + if uint(data[14]) == 0 { + m.Setup = true + } + + if uint(data[15]) == 0 { + m.Data = true + } + + m.TimestampSec = int64(binary.LittleEndian.Uint64(data[16:24])) + m.TimestampUsec = int32(binary.LittleEndian.Uint32(data[24:28])) + m.Status = int32(binary.LittleEndian.Uint32(data[28:32])) + m.UrbLength = binary.LittleEndian.Uint32(data[32:36]) + m.UrbDataLength = binary.LittleEndian.Uint32(data[36:40]) + + m.Contents = data[:40] + m.Payload = data[40:] + + if m.Setup { + m.Payload = data[40:] + } else if m.Data { + m.Payload = data[uint32(len(data))-m.UrbDataLength:] + } + + // if 64 bit, dissect_linux_usb_pseudo_header_ext + if false { + m.UrbInterval = binary.LittleEndian.Uint32(data[40:44]) + m.UrbStartFrame = binary.LittleEndian.Uint32(data[44:48]) + m.UrbDataLength = binary.LittleEndian.Uint32(data[48:52]) + m.IsoNumDesc = binary.LittleEndian.Uint32(data[52:56]) + m.Contents = data[:56] + m.Payload = data[56:] + } + + // crc5 or crc16 + // eop (end of packet) + + return nil +} + +type USBRequestBlockSetup struct { + BaseLayer + RequestType uint8 + Request USBRequestBlockSetupRequest + Value uint16 + Index uint16 + Length uint16 +} + +func (u *USBRequestBlockSetup) LayerType() gopacket.LayerType { return LayerTypeUSBRequestBlockSetup } + +func (m *USBRequestBlockSetup) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypePayload +} + +func (m *USBRequestBlockSetup) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + m.RequestType = data[0] + m.Request = USBRequestBlockSetupRequest(data[1]) + m.Value = binary.LittleEndian.Uint16(data[2:4]) + m.Index = binary.LittleEndian.Uint16(data[4:6]) + m.Length = binary.LittleEndian.Uint16(data[6:8]) + m.Contents = data[:8] + m.Payload = data[8:] + return nil +} + +func decodeUSBRequestBlockSetup(data []byte, p gopacket.PacketBuilder) error { + d := &USBRequestBlockSetup{} + return decodingLayerDecoder(d, data, p) +} + +type USBControl struct { + BaseLayer +} + +func (u *USBControl) LayerType() gopacket.LayerType { return LayerTypeUSBControl } + +func (m *USBControl) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypePayload +} + +func (m *USBControl) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + m.Contents = data + return nil +} + +func decodeUSBControl(data []byte, p gopacket.PacketBuilder) error { + d := &USBControl{} + return decodingLayerDecoder(d, data, p) +} + +type USBInterrupt struct { + BaseLayer +} + +func (u *USBInterrupt) LayerType() gopacket.LayerType { return LayerTypeUSBInterrupt } + +func (m *USBInterrupt) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypePayload +} + +func (m *USBInterrupt) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + m.Contents = data + return nil +} + +func decodeUSBInterrupt(data []byte, p gopacket.PacketBuilder) error { + d := &USBInterrupt{} + return decodingLayerDecoder(d, data, p) +} + +type USBBulk struct { + BaseLayer +} + +func (u *USBBulk) LayerType() gopacket.LayerType { return LayerTypeUSBBulk } + +func (m *USBBulk) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypePayload +} + +func (m *USBBulk) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + m.Contents = data + return nil +} + +func decodeUSBBulk(data []byte, p gopacket.PacketBuilder) error { + d := &USBBulk{} + return decodingLayerDecoder(d, data, p) +} diff --git a/vendor/github.com/google/gopacket/layers/usb_test.go b/vendor/github.com/google/gopacket/layers/usb_test.go new file mode 100644 index 0000000..35e9c70 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/usb_test.go @@ -0,0 +1,73 @@ +// Copyright 2014, Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + _ "fmt" + "github.com/google/gopacket" + "reflect" + "testing" +) + +// Generator python layers/test_creator.py --link_type USB --name USB dongle.pcap +// http://wiki.wireshark.org/SampleCaptures#Sample_Captures + +// testPacketUSB0 is the packet: +// 02:41:04.689546 INTERRUPT COMPLETE to 2:1:1 +// 0x0000: 0038 4a3b 0088 ffff 4301 8101 0200 2d00 .8J;....C.....-. +// 0x0010: c0d3 5b50 0000 0000 8a85 0a00 0000 0000 ..[P............ +// 0x0020: 0100 0000 0100 0000 0000 0000 0000 0000 ................ +// 0x0030: 8000 0000 0000 0000 0002 0000 0000 0000 ................ +// 0x0040: 04 . +var testPacketUSB0 = []byte{ + 0x00, 0x38, 0x4a, 0x3b, 0x00, 0x88, 0xff, 0xff, 0x43, 0x01, 0x81, 0x01, 0x02, 0x00, 0x2d, 0x00, + 0xc0, 0xd3, 0x5b, 0x50, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x85, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, +} + +func TestPacketUSB0(t *testing.T) { + p := gopacket.NewPacket(testPacketUSB0, LinkTypeLinuxUSB, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeUSB, LayerTypeUSBInterrupt}, t) + + if got, ok := p.Layer(LayerTypeUSB).(*USB); ok { + want := &USB{ + BaseLayer: BaseLayer{ + Contents: []uint8{0x0, 0x38, 0x4a, 0x3b, 0x0, 0x88, 0xff, 0xff, 0x43, 0x1, 0x81, 0x1, 0x2, 0x0, 0x2d, 0x0, 0xc0, 0xd3, 0x5b, 0x50, 0x0, 0x0, 0x0, 0x0, 0x8a, 0x85, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0}, + Payload: []uint8{0x4}, + }, + ID: 0xffff88003b4a3800, + EventType: USBEventTypeComplete, + TransferType: USBTransportTypeInterrupt, + Direction: 0x1, + EndpointNumber: 0x1, + DeviceAddress: 0x1, + BusID: 0x2, + TimestampSec: 1348195264, + TimestampUsec: 689546, + Setup: false, + Data: true, + Status: 0, + UrbLength: 0x1, + UrbDataLength: 0x1, + } + + if !reflect.DeepEqual(got, want) { + t.Errorf("USB packet processing failed:\ngot :\n%#v\n\nwant :\n%#v\n\n", got, want) + } + } + +} +func BenchmarkDecodePacketUSB0(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketUSB0, LinkTypeLinuxUSB, gopacket.NoCopy) + } +} diff --git a/vendor/github.com/google/gopacket/layers/vrrp.go b/vendor/github.com/google/gopacket/layers/vrrp.go new file mode 100644 index 0000000..ffaafe6 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/vrrp.go @@ -0,0 +1,156 @@ +// Copyright 2016 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "errors" + "net" + + "github.com/google/gopacket" +) + +/* + This layer provides decoding for Virtual Router Redundancy Protocol (VRRP) v2. + https://tools.ietf.org/html/rfc3768#section-5 + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |Version| Type | Virtual Rtr ID| Priority | Count IP Addrs| + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Auth Type | Adver Int | Checksum | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | IP Address (1) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | . | + | . | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | IP Address (n) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Authentication Data (1) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Authentication Data (2) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ + +type VRRPv2Type uint8 +type VRRPv2AuthType uint8 + +const ( + VRRPv2Advertisement VRRPv2Type = 0x01 // router advertisement +) + +// String conversions for VRRP message types +func (v VRRPv2Type) String() string { + switch v { + case VRRPv2Advertisement: + return "VRRPv2 Advertisement" + default: + return "" + } +} + +const ( + VRRPv2AuthNoAuth VRRPv2AuthType = 0x00 // No Authentication + VRRPv2AuthReserved1 VRRPv2AuthType = 0x01 // Reserved field 1 + VRRPv2AuthReserved2 VRRPv2AuthType = 0x02 // Reserved field 2 +) + +func (v VRRPv2AuthType) String() string { + switch v { + case VRRPv2AuthNoAuth: + return "No Authentication" + case VRRPv2AuthReserved1: + return "Reserved" + case VRRPv2AuthReserved2: + return "Reserved" + default: + return "" + } +} + +// VRRPv2 represents an VRRP v2 message. +type VRRPv2 struct { + BaseLayer + Version uint8 // The version field specifies the VRRP protocol version of this packet (v2) + Type VRRPv2Type // The type field specifies the type of this VRRP packet. The only type defined in v2 is ADVERTISEMENT + VirtualRtrID uint8 // identifies the virtual router this packet is reporting status for + Priority uint8 // specifies the sending VRRP router's priority for the virtual router (100 = default) + CountIPAddr uint8 // The number of IP addresses contained in this VRRP advertisement. + AuthType VRRPv2AuthType // identifies the authentication method being utilized + AdverInt uint8 // The Advertisement interval indicates the time interval (in seconds) between ADVERTISEMENTS. The default is 1 second + Checksum uint16 // used to detect data corruption in the VRRP message. + IPAddress []net.IP // one or more IP addresses associated with the virtual router. Specified in the CountIPAddr field. +} + +// LayerType returns LayerTypeVRRP for VRRP v2 message. +func (v *VRRPv2) LayerType() gopacket.LayerType { return LayerTypeVRRP } + +func (v *VRRPv2) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + + v.BaseLayer = BaseLayer{Contents: data[:len(data)]} + v.Version = data[0] >> 4 // high nibble == VRRP version. We're expecting v2 + + v.Type = VRRPv2Type(data[0] & 0x0F) // low nibble == VRRP type. Expecting 1 (advertisement) + if v.Type != 1 { + // rfc3768: A packet with unknown type MUST be discarded. + return errors.New("Unrecognized VRRPv2 type field.") + } + + v.VirtualRtrID = data[1] + v.Priority = data[2] + + v.CountIPAddr = data[3] + if v.CountIPAddr < 1 { + return errors.New("VRRPv2 number of IP addresses is not valid.") + } + + v.AuthType = VRRPv2AuthType(data[4]) + v.AdverInt = uint8(data[5]) + v.Checksum = binary.BigEndian.Uint16(data[6:8]) + + // populate the IPAddress field. The number of addresses is specified in the v.CountIPAddr field + // offset references the starting byte containing the list of ip addresses + offset := 8 + for i := uint8(0); i < v.CountIPAddr; i++ { + v.IPAddress = append(v.IPAddress, data[offset:offset+4]) + offset += 4 + } + + // any trailing packets here may be authentication data and *should* be ignored in v2 as per RFC + // + // 5.3.10. Authentication Data + // + // The authentication string is currently only used to maintain + // backwards compatibility with RFC 2338. It SHOULD be set to zero on + // transmission and ignored on reception. + return nil +} + +// CanDecode specifies the layer type in which we are attempting to unwrap. +func (v *VRRPv2) CanDecode() gopacket.LayerClass { + return LayerTypeVRRP +} + +// NextLayerType specifies the next layer that should be decoded. VRRP does not contain any further payload, so we set to 0 +func (v *VRRPv2) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypeZero +} + +// The VRRP packet does not include payload data. Setting byte slice to nil +func (v *VRRPv2) Payload() []byte { + return nil +} + +// decodeVRRP will parse VRRP v2 +func decodeVRRP(data []byte, p gopacket.PacketBuilder) error { + if len(data) < 8 { + return errors.New("Not a valid VRRP packet. Packet length is too small.") + } + v := &VRRPv2{} + return decodingLayerDecoder(v, data, p) +} diff --git a/vendor/github.com/google/gopacket/layers/vrrp_test.go b/vendor/github.com/google/gopacket/layers/vrrp_test.go new file mode 100644 index 0000000..bc6b7e4 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/vrrp_test.go @@ -0,0 +1,55 @@ +// Copyright 2016 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. +package layers + +import ( + "github.com/google/gopacket" + "testing" +) + +// vrrpPacketPriority100 is the packet: +// 06:12:21.813317 IP 192.168.0.30 > 224.0.0.18: VRRPv2, Advertisement, vrid 1, prio 100, authtype none, intvl 1s, length 20 +// 0x0000: 0100 5e00 0012 0000 5e00 0101 0800 45c0 ..^.....^.....E. +// 0x0010: 0028 0000 0000 ff70 19cd c0a8 001e e000 .(.....p........ +// 0x0020: 0012 2101 6401 0001 ba52 c0a8 0001 0000 ..!.d....R...... +// 0x0030: 0000 0000 0000 0000 0000 0000 ............ +var vrrpPacketPriority100 = []byte{ + 0x01, 0x00, 0x5e, 0x00, 0x00, 0x12, 0x00, 0x00, 0x5e, 0x00, 0x01, 0x01, 0x08, 0x00, 0x45, 0xc0, + 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0xff, 0x70, 0x19, 0xcd, 0xc0, 0xa8, 0x00, 0x1e, 0xe0, 0x00, + 0x00, 0x12, 0x21, 0x01, 0x64, 0x01, 0x00, 0x01, 0xba, 0x52, 0xc0, 0xa8, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +} + +func TestVRRPPacketPacket0(t *testing.T) { + p := gopacket.NewPacket(vrrpPacketPriority100, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeVRRP}, t) + + // Version=2 Type=VRRPv2 Advertisement VirtualRtrID=1 Priority=100 + vrrp := p.Layer(LayerTypeVRRP).(*VRRPv2) + if vrrp.Version != 2 { + t.Fatalf("Unable to decode VRRPv2 version. Received %d, expected %d", vrrp.Version, 2) + } + + if vrrp.Type != 1 { + t.Fatalf("Unable to decode VRRPv2 type. Received %d, expected %d", vrrp.Type, 1) + } + + if vrrp.Priority != 100 { + t.Fatalf("Unable to decode VRRPv2 priority. Received %d, expected %d", vrrp.Priority, 100) + } + + if vrrp.Checksum != 47698 { + t.Fatalf("Unable to decode VRRPv2 checksum. Received %d, expected %d", vrrp.Checksum, 47698) + } +} +func BenchmarkDecodeVRRPPacket0(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(vrrpPacketPriority100, LayerTypeEthernet, gopacket.NoCopy) + } +} diff --git a/vendor/github.com/google/gopacket/layers/vxlan.go b/vendor/github.com/google/gopacket/layers/vxlan.go new file mode 100644 index 0000000..08f1ecb --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/vxlan.go @@ -0,0 +1,94 @@ +// Copyright 2016 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "fmt" + "github.com/google/gopacket" +) + +// VXLAN is specifed in RFC 7348 https://tools.ietf.org/html/rfc7348 +// G, D, A, Group Policy ID from https://tools.ietf.org/html/draft-smith-vxlan-group-policy-00 +// 0 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// 0 8 16 24 32 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// |G|R|R|R|I|R|R|R|R|D|R|R|A|R|R|R| Group Policy ID | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | 24 bit VXLAN Network Identifier | Reserved | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +// VXLAN is a VXLAN packet header +type VXLAN struct { + BaseLayer + ValidIDFlag bool // 'I' bit per RFC 7348 + VNI uint32 // 'VXLAN Network Identifier' 24 bits per RFC 7348 + GBPExtension bool // 'G' bit per Group Policy https://tools.ietf.org/html/draft-smith-vxlan-group-policy-00 + GBPDontLearn bool // 'D' bit per Group Policy + GBPApplied bool // 'A' bit per Group Policy + GBPGroupPolicyID uint16 // 'Group Policy ID' 16 bits per Group Policy +} + +// LayerType returns LayerTypeVXLAN +func (vx *VXLAN) LayerType() gopacket.LayerType { return LayerTypeVXLAN } + +func decodeVXLAN(data []byte, p gopacket.PacketBuilder) error { + vx := &VXLAN{} + + // VNI is a 24bit number, Uint32 requires 32 bits + var buf [4]byte + copy(buf[1:], data[4:7]) + + // RFC 7348 https://tools.ietf.org/html/rfc7348 + vx.ValidIDFlag = data[0]&0x08 > 0 // 'I' bit per RFC7348 + vx.VNI = binary.BigEndian.Uint32(buf[:]) // VXLAN Network Identifier per RFC7348 + + // Group Based Policy https://tools.ietf.org/html/draft-smith-vxlan-group-policy-00 + vx.GBPExtension = data[0]&0x80 > 0 // 'G' bit per the group policy draft + vx.GBPDontLearn = data[1]&0x40 > 0 // 'D' bit - the egress VTEP MUST NOT learn the source address of the encapsulated frame. + vx.GBPApplied = data[1]&0x80 > 0 // 'A' bit - indicates that the group policy has already been applied to this packet. + vx.GBPGroupPolicyID = binary.BigEndian.Uint16(data[2:4]) // Policy ID as per the group policy draft + + // Layer information + const vxlanLength = 8 + vx.Contents = data[:vxlanLength] + vx.Payload = data[vxlanLength:] + + p.AddLayer(vx) + return p.NextDecoder(LinkTypeEthernet) +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (vx *VXLAN) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + bytes, err := b.PrependBytes(8) + if err != nil { + return err + } + + if vx.ValidIDFlag { + bytes[0] |= 0x08 + } + if vx.GBPExtension { + bytes[0] |= 0x80 + } + if vx.GBPDontLearn { + bytes[1] |= 0x40 + } + if vx.GBPApplied { + bytes[1] |= 0x80 + } + + binary.BigEndian.PutUint16(bytes[2:4], vx.GBPGroupPolicyID) + if vx.VNI >= 1<<24 { + return fmt.Errorf("Virtual Network Identifier = %x exceeds max for 24-bit uint", vx.VNI) + } + binary.BigEndian.PutUint32(bytes[4:8], vx.VNI<<8) + return nil +} diff --git a/vendor/github.com/google/gopacket/layers/vxlan_test.go b/vendor/github.com/google/gopacket/layers/vxlan_test.go new file mode 100644 index 0000000..a02d934 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/vxlan_test.go @@ -0,0 +1,108 @@ +// Copyright 2016 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "github.com/google/gopacket" + "reflect" + "testing" +) + +// VXLAN is specifed in RFC 7348 +// 0 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// 0 8 16 24 32 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// |G|R|R|R|I|R|R|R|R|D|R|R|A|R|R|R| Group Policy ID | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | 24 bit VXLAN Network Identifier | Reserved | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +// Ethernet[IP[UDP[VXLAN[Ethernet[IP[ICMP]]]]]] + +// testPacketVXLAN +// 0000 00 16 3e 08 71 cf 36 dc 85 1e b3 40 08 00 45 00 ..>.q.6....@..E. +// 0010 00 86 d2 c0 40 00 40 11 51 52 c0 a8 cb 01 c0 a8 ....@.@.QR...... +// 0020 ca 01 b0 5d 12 b5 00 72 00 00 08 00 00 00 00 00 ...]...r........ +// 0030 00 00 00 30 88 01 00 02 00 16 3e 37 f6 04 08 00 ...0......>7.... +// 0040 45 00 00 54 00 00 40 00 40 01 23 4f c0 a8 cb 03 E..T..@.@.#O.... +// 0050 c0 a8 cb 05 08 00 f6 f2 05 0c 00 01 fc e2 97 51 ...............Q +// 0060 00 00 00 00 a6 f8 02 00 00 00 00 00 10 11 12 13 ................ +// 0070 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 ............ !"# +// 0080 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 $%&'()*+,-./0123 +// 0090 34 35 36 37 4567 ./01234567 +var testPacketVXLAN = []byte{ + 0x00, 0x16, 0x3e, 0x08, 0x71, 0xcf, 0x36, 0xdc, 0x85, 0x1e, 0xb3, 0x40, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x86, 0xd2, 0xc0, 0x40, 0x00, 0x40, 0x11, 0x51, 0x52, 0xc0, 0xa8, 0xcb, 0x01, 0xc0, 0xa8, + 0xca, 0x01, 0xb0, 0x5d, 0x12, 0xb5, 0x00, 0x72, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x30, 0x88, 0x01, 0x00, 0x02, 0x00, 0x16, 0x3e, 0x37, 0xf6, 0x04, 0x08, 0x00, + 0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00, 0x40, 0x01, 0x23, 0x4f, 0xc0, 0xa8, 0xcb, 0x03, + 0xc0, 0xa8, 0xcb, 0x05, 0x08, 0x00, 0xf6, 0xf2, 0x05, 0x0c, 0x00, 0x01, 0xfc, 0xe2, 0x97, 0x51, + 0x00, 0x00, 0x00, 0x00, 0xa6, 0xf8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, +} + +func TestPacketVXLAN(t *testing.T) { + p := gopacket.NewPacket(testPacketVXLAN, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeUDP, LayerTypeVXLAN, LayerTypeEthernet, LayerTypeIPv4, LayerTypeICMPv4, gopacket.LayerTypePayload}, t) + if got, ok := p.Layer(LayerTypeVXLAN).(*VXLAN); ok { + want := &VXLAN{ + BaseLayer: BaseLayer{ + Contents: []byte{0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00}, + Payload: []byte{0x00, 0x30, 0x88, 0x01, 0x00, 0x02, 0x00, 0x16, 0x3e, 0x37, 0xf6, 0x04, 0x08, 0x00, + 0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00, 0x40, 0x01, 0x23, 0x4f, 0xc0, 0xa8, 0xcb, 0x03, + 0xc0, 0xa8, 0xcb, 0x05, 0x08, 0x00, 0xf6, 0xf2, 0x05, 0x0c, 0x00, 0x01, 0xfc, 0xe2, 0x97, 0x51, + 0x00, 0x00, 0x00, 0x00, 0xa6, 0xf8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37}, + }, + ValidIDFlag: true, + VNI: 255, + GBPExtension: false, + GBPApplied: false, + GBPDontLearn: false, + GBPGroupPolicyID: 0, + } + if !reflect.DeepEqual(want, got) { + t.Errorf("VXLAN layer mismatch, \nwant %#v\ngot %#v\n", want, got) + } + } +} + +func BenchmarkDecodePacketVXLAN(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketVXLAN, LinkTypeEthernet, gopacket.NoCopy) + } +} + +func TestIsomorphicPacketVXLAN(t *testing.T) { + vx := &VXLAN{ + ValidIDFlag: true, + VNI: 255, + GBPExtension: true, + GBPApplied: true, + GBPDontLearn: true, + GBPGroupPolicyID: 777, + } + + b := gopacket.NewSerializeBuffer() + vx.SerializeTo(b, gopacket.SerializeOptions{}) + + p := gopacket.NewPacket(b.Bytes(), gopacket.DecodeFunc(decodeVXLAN), gopacket.Default) + vxTranslated := p.Layer(LayerTypeVXLAN).(*VXLAN) + vxTranslated.BaseLayer = BaseLayer{} + + if !reflect.DeepEqual(vx, vxTranslated) { + t.Errorf("VXLAN isomorph mismatch, \nwant %#v\ngot %#v\n", vx, vxTranslated) + } +} |