rudp.go 2.8 KB

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