Fix unit tests
[govpp.git] / vendor / github.com / google / gopacket / layers / rudp.go
1 // Copyright 2012 Google, Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style license
4 // that can be found in the LICENSE file in the root of the source
5 // tree.
6
7 package layers
8
9 import (
10         "encoding/binary"
11         "fmt"
12         "github.com/google/gopacket"
13 )
14
15 type RUDP struct {
16         BaseLayer
17         SYN, ACK, EACK, RST, NUL bool
18         Version                  uint8
19         HeaderLength             uint8
20         SrcPort, DstPort         RUDPPort
21         DataLength               uint16
22         Seq, Ack, Checksum       uint32
23         VariableHeaderArea       []byte
24         // RUDPHeaderSyn contains SYN information for the RUDP packet,
25         // if the SYN flag is set
26         *RUDPHeaderSYN
27         // RUDPHeaderEack contains EACK information for the RUDP packet,
28         // if the EACK flag is set.
29         *RUDPHeaderEACK
30 }
31
32 type RUDPHeaderSYN struct {
33         MaxOutstandingSegments, MaxSegmentSize, OptionFlags uint16
34 }
35
36 type RUDPHeaderEACK struct {
37         SeqsReceivedOK []uint32
38 }
39
40 // LayerType returns gopacket.LayerTypeRUDP.
41 func (r *RUDP) LayerType() gopacket.LayerType { return LayerTypeRUDP }
42
43 func decodeRUDP(data []byte, p gopacket.PacketBuilder) error {
44         r := &RUDP{
45                 SYN:          data[0]&0x80 != 0,
46                 ACK:          data[0]&0x40 != 0,
47                 EACK:         data[0]&0x20 != 0,
48                 RST:          data[0]&0x10 != 0,
49                 NUL:          data[0]&0x08 != 0,
50                 Version:      data[0] & 0x3,
51                 HeaderLength: data[1],
52                 SrcPort:      RUDPPort(data[2]),
53                 DstPort:      RUDPPort(data[3]),
54                 DataLength:   binary.BigEndian.Uint16(data[4:6]),
55                 Seq:          binary.BigEndian.Uint32(data[6:10]),
56                 Ack:          binary.BigEndian.Uint32(data[10:14]),
57                 Checksum:     binary.BigEndian.Uint32(data[14:18]),
58         }
59         if r.HeaderLength < 9 {
60                 return fmt.Errorf("RUDP packet with too-short header length %d", r.HeaderLength)
61         }
62         hlen := int(r.HeaderLength) * 2
63         r.Contents = data[:hlen]
64         r.Payload = data[hlen : hlen+int(r.DataLength)]
65         r.VariableHeaderArea = data[18:hlen]
66         headerData := r.VariableHeaderArea
67         switch {
68         case r.SYN:
69                 if len(headerData) != 6 {
70                         return fmt.Errorf("RUDP packet invalid SYN header length: %d", len(headerData))
71                 }
72                 r.RUDPHeaderSYN = &RUDPHeaderSYN{
73                         MaxOutstandingSegments: binary.BigEndian.Uint16(headerData[:2]),
74                         MaxSegmentSize:         binary.BigEndian.Uint16(headerData[2:4]),
75                         OptionFlags:            binary.BigEndian.Uint16(headerData[4:6]),
76                 }
77         case r.EACK:
78                 if len(headerData)%4 != 0 {
79                         return fmt.Errorf("RUDP packet invalid EACK header length: %d", len(headerData))
80                 }
81                 r.RUDPHeaderEACK = &RUDPHeaderEACK{make([]uint32, len(headerData)/4)}
82                 for i := 0; i < len(headerData); i += 4 {
83                         r.SeqsReceivedOK[i/4] = binary.BigEndian.Uint32(headerData[i : i+4])
84                 }
85         }
86         p.AddLayer(r)
87         p.SetTransportLayer(r)
88         return p.NextDecoder(gopacket.LayerTypePayload)
89 }
90
91 func (r *RUDP) TransportFlow() gopacket.Flow {
92         return gopacket.NewFlow(EndpointRUDPPort, []byte{byte(r.SrcPort)}, []byte{byte(r.DstPort)})
93 }