gtp.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // Copyright 2017 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. import (
  9. "encoding/binary"
  10. "fmt"
  11. "github.com/google/gopacket"
  12. )
  13. const gtpMinimumSizeInBytes int = 8
  14. // GTPExtensionHeader is used to carry extra data and enable future extensions of the GTP without the need to use another version number.
  15. type GTPExtensionHeader struct {
  16. Type uint8
  17. Content []byte
  18. }
  19. // GTPv1U protocol is used to exchange user data over GTP tunnels across the Sx interfaces.
  20. // Defined in https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1595
  21. type GTPv1U struct {
  22. BaseLayer
  23. Version uint8
  24. ProtocolType uint8
  25. Reserved uint8
  26. ExtensionHeaderFlag bool
  27. SequenceNumberFlag bool
  28. NPDUFlag bool
  29. MessageType uint8
  30. MessageLength uint16
  31. TEID uint32
  32. SequenceNumber uint16
  33. NPDU uint8
  34. GTPExtensionHeaders []GTPExtensionHeader
  35. }
  36. // LayerType returns LayerTypeGTPV1U
  37. func (g *GTPv1U) LayerType() gopacket.LayerType { return LayerTypeGTPv1U }
  38. // DecodeFromBytes analyses a byte slice and attempts to decode it as a GTPv1U packet
  39. func (g *GTPv1U) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  40. hLen := gtpMinimumSizeInBytes
  41. dLen := len(data)
  42. if dLen < hLen {
  43. return fmt.Errorf("GTP packet too small: %d bytes", dLen)
  44. }
  45. g.Version = (data[0] >> 5) & 0x07
  46. g.ProtocolType = (data[0] >> 4) & 0x01
  47. g.Reserved = (data[0] >> 3) & 0x01
  48. g.SequenceNumberFlag = ((data[0] >> 1) & 0x01) == 1
  49. g.NPDUFlag = (data[0] & 0x01) == 1
  50. g.ExtensionHeaderFlag = ((data[0] >> 2) & 0x01) == 1
  51. g.MessageType = data[1]
  52. g.MessageLength = binary.BigEndian.Uint16(data[2:4])
  53. pLen := 8 + g.MessageLength
  54. if uint16(dLen) < pLen {
  55. return fmt.Errorf("GTP packet too small: %d bytes", dLen)
  56. }
  57. // Field used to multiplex different connections in the same GTP tunnel.
  58. g.TEID = binary.BigEndian.Uint32(data[4:8])
  59. cIndex := uint16(hLen)
  60. if g.SequenceNumberFlag || g.NPDUFlag || g.ExtensionHeaderFlag {
  61. hLen += 4
  62. cIndex += 4
  63. if dLen < hLen {
  64. return fmt.Errorf("GTP packet too small: %d bytes", dLen)
  65. }
  66. if g.SequenceNumberFlag {
  67. g.SequenceNumber = binary.BigEndian.Uint16(data[8:10])
  68. }
  69. if g.NPDUFlag {
  70. g.NPDU = data[10]
  71. }
  72. if g.ExtensionHeaderFlag {
  73. extensionFlag := true
  74. for extensionFlag {
  75. extensionType := uint8(data[cIndex-1])
  76. extensionLength := uint(data[cIndex])
  77. if extensionLength == 0 {
  78. return fmt.Errorf("GTP packet with invalid extension header")
  79. }
  80. // extensionLength is in 4-octet units
  81. lIndex := cIndex + (uint16(extensionLength) * 4)
  82. if uint16(dLen) < lIndex {
  83. fmt.Println(dLen, lIndex)
  84. return fmt.Errorf("GTP packet with small extension header: %d bytes", dLen)
  85. }
  86. content := data[cIndex+1 : lIndex-1]
  87. eh := GTPExtensionHeader{Type: extensionType, Content: content}
  88. g.GTPExtensionHeaders = append(g.GTPExtensionHeaders, eh)
  89. cIndex = lIndex
  90. // Check if coming bytes are from an extension header
  91. extensionFlag = data[cIndex-1] != 0
  92. }
  93. }
  94. }
  95. g.BaseLayer = BaseLayer{Contents: data[:cIndex], Payload: data[cIndex:]}
  96. return nil
  97. }
  98. // SerializeTo writes the serialized form of this layer into the
  99. // SerializationBuffer, implementing gopacket.SerializableLayer.
  100. // See the docs for gopacket.SerializableLayer for more info.
  101. func (g *GTPv1U) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  102. data, err := b.PrependBytes(gtpMinimumSizeInBytes)
  103. if err != nil {
  104. return err
  105. }
  106. data[0] |= (g.Version << 5)
  107. data[0] |= (1 << 4)
  108. if len(g.GTPExtensionHeaders) > 0 {
  109. data[0] |= 0x04
  110. g.ExtensionHeaderFlag = true
  111. }
  112. if g.SequenceNumberFlag {
  113. data[0] |= 0x02
  114. }
  115. if g.NPDUFlag {
  116. data[0] |= 0x01
  117. }
  118. data[1] = g.MessageType
  119. binary.BigEndian.PutUint16(data[2:4], g.MessageLength)
  120. binary.BigEndian.PutUint32(data[4:8], g.TEID)
  121. if g.ExtensionHeaderFlag || g.SequenceNumberFlag || g.NPDUFlag {
  122. data, err := b.AppendBytes(4)
  123. if err != nil {
  124. return err
  125. }
  126. binary.BigEndian.PutUint16(data[:2], g.SequenceNumber)
  127. data[2] = g.NPDU
  128. for _, eh := range g.GTPExtensionHeaders {
  129. data[len(data)-1] = eh.Type
  130. lContent := len(eh.Content)
  131. // extensionLength is in 4-octet units
  132. extensionLength := (lContent + 2) / 4
  133. // Get two extra byte for the next extension header type and length
  134. data, err = b.AppendBytes(lContent + 2)
  135. if err != nil {
  136. return err
  137. }
  138. data[0] = byte(extensionLength)
  139. copy(data[1:lContent+1], eh.Content)
  140. }
  141. }
  142. return nil
  143. }
  144. // CanDecode returns a set of layers that GTP objects can decode.
  145. func (g *GTPv1U) CanDecode() gopacket.LayerClass {
  146. return LayerTypeGTPv1U
  147. }
  148. // NextLayerType specifies the next layer that GoPacket should attempt to
  149. func (g *GTPv1U) NextLayerType() gopacket.LayerType {
  150. version := uint8(g.LayerPayload()[0]) >> 4
  151. if version == 4 {
  152. return LayerTypeIPv4
  153. } else if version == 6 {
  154. return LayerTypeIPv6
  155. } else {
  156. return LayerTypePPP
  157. }
  158. }
  159. func decodeGTPv1u(data []byte, p gopacket.PacketBuilder) error {
  160. gtp := &GTPv1U{}
  161. err := gtp.DecodeFromBytes(data, p)
  162. if err != nil {
  163. return err
  164. }
  165. p.AddLayer(gtp)
  166. return p.NextDecoder(gtp.NextLayerType())
  167. }