aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/google/gopacket/layers/rudp.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/google/gopacket/layers/rudp.go')
-rw-r--r--vendor/github.com/google/gopacket/layers/rudp.go93
1 files changed, 93 insertions, 0 deletions
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)})
+}