gre.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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. "github.com/google/gopacket"
  10. )
  11. // GRE is a Generic Routing Encapsulation header.
  12. type GRE struct {
  13. BaseLayer
  14. ChecksumPresent, RoutingPresent, KeyPresent, SeqPresent, StrictSourceRoute, AckPresent bool
  15. RecursionControl, Flags, Version uint8
  16. Protocol EthernetType
  17. Checksum, Offset uint16
  18. Key, Seq, Ack uint32
  19. *GRERouting
  20. }
  21. // GRERouting is GRE routing information, present if the RoutingPresent flag is
  22. // set.
  23. type GRERouting struct {
  24. AddressFamily uint16
  25. SREOffset, SRELength uint8
  26. RoutingInformation []byte
  27. Next *GRERouting
  28. }
  29. // LayerType returns gopacket.LayerTypeGRE.
  30. func (g *GRE) LayerType() gopacket.LayerType { return LayerTypeGRE }
  31. // DecodeFromBytes decodes the given bytes into this layer.
  32. func (g *GRE) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  33. g.ChecksumPresent = data[0]&0x80 != 0
  34. g.RoutingPresent = data[0]&0x40 != 0
  35. g.KeyPresent = data[0]&0x20 != 0
  36. g.SeqPresent = data[0]&0x10 != 0
  37. g.StrictSourceRoute = data[0]&0x08 != 0
  38. g.AckPresent = data[1]&0x80 != 0
  39. g.RecursionControl = data[0] & 0x7
  40. g.Flags = data[1] >> 3
  41. g.Version = data[1] & 0x7
  42. g.Protocol = EthernetType(binary.BigEndian.Uint16(data[2:4]))
  43. offset := 4
  44. if g.ChecksumPresent || g.RoutingPresent {
  45. g.Checksum = binary.BigEndian.Uint16(data[offset : offset+2])
  46. g.Offset = binary.BigEndian.Uint16(data[offset+2 : offset+4])
  47. offset += 4
  48. }
  49. if g.KeyPresent {
  50. g.Key = binary.BigEndian.Uint32(data[offset : offset+4])
  51. offset += 4
  52. }
  53. if g.SeqPresent {
  54. g.Seq = binary.BigEndian.Uint32(data[offset : offset+4])
  55. offset += 4
  56. }
  57. if g.RoutingPresent {
  58. tail := &g.GRERouting
  59. for {
  60. sre := &GRERouting{
  61. AddressFamily: binary.BigEndian.Uint16(data[offset : offset+2]),
  62. SREOffset: data[offset+2],
  63. SRELength: data[offset+3],
  64. }
  65. sre.RoutingInformation = data[offset+4 : offset+4+int(sre.SRELength)]
  66. offset += 4 + int(sre.SRELength)
  67. if sre.AddressFamily == 0 && sre.SRELength == 0 {
  68. break
  69. }
  70. (*tail) = sre
  71. tail = &sre.Next
  72. }
  73. }
  74. if g.AckPresent {
  75. g.Ack = binary.BigEndian.Uint32(data[offset : offset+4])
  76. offset += 4
  77. }
  78. g.BaseLayer = BaseLayer{data[:offset], data[offset:]}
  79. return nil
  80. }
  81. // SerializeTo writes the serialized form of this layer into the SerializationBuffer,
  82. // implementing gopacket.SerializableLayer. See the docs for gopacket.SerializableLayer for more info.
  83. func (g *GRE) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  84. size := 4
  85. if g.ChecksumPresent || g.RoutingPresent {
  86. size += 4
  87. }
  88. if g.KeyPresent {
  89. size += 4
  90. }
  91. if g.SeqPresent {
  92. size += 4
  93. }
  94. if g.RoutingPresent {
  95. r := g.GRERouting
  96. for r != nil {
  97. size += 4 + int(r.SRELength)
  98. r = r.Next
  99. }
  100. size += 4
  101. }
  102. if g.AckPresent {
  103. size += 4
  104. }
  105. buf, err := b.PrependBytes(size)
  106. if err != nil {
  107. return err
  108. }
  109. // Reset any potentially dirty memory in the first 2 bytes, as these use OR to set flags.
  110. buf[0] = 0
  111. buf[1] = 0
  112. if g.ChecksumPresent {
  113. buf[0] |= 0x80
  114. }
  115. if g.RoutingPresent {
  116. buf[0] |= 0x40
  117. }
  118. if g.KeyPresent {
  119. buf[0] |= 0x20
  120. }
  121. if g.SeqPresent {
  122. buf[0] |= 0x10
  123. }
  124. if g.StrictSourceRoute {
  125. buf[0] |= 0x08
  126. }
  127. if g.AckPresent {
  128. buf[1] |= 0x80
  129. }
  130. buf[0] |= g.RecursionControl
  131. buf[1] |= g.Flags << 3
  132. buf[1] |= g.Version
  133. binary.BigEndian.PutUint16(buf[2:4], uint16(g.Protocol))
  134. offset := 4
  135. if g.ChecksumPresent || g.RoutingPresent {
  136. // Don't write the checksum value yet, as we may need to compute it,
  137. // which requires the entire header be complete.
  138. // Instead we zeroize the memory in case it is dirty.
  139. buf[offset] = 0
  140. buf[offset+1] = 0
  141. binary.BigEndian.PutUint16(buf[offset+2:offset+4], g.Offset)
  142. offset += 4
  143. }
  144. if g.KeyPresent {
  145. binary.BigEndian.PutUint32(buf[offset:offset+4], g.Key)
  146. offset += 4
  147. }
  148. if g.SeqPresent {
  149. binary.BigEndian.PutUint32(buf[offset:offset+4], g.Seq)
  150. offset += 4
  151. }
  152. if g.RoutingPresent {
  153. sre := g.GRERouting
  154. for sre != nil {
  155. binary.BigEndian.PutUint16(buf[offset:offset+2], sre.AddressFamily)
  156. buf[offset+2] = sre.SREOffset
  157. buf[offset+3] = sre.SRELength
  158. copy(buf[offset+4:offset+4+int(sre.SRELength)], sre.RoutingInformation)
  159. offset += 4 + int(sre.SRELength)
  160. sre = sre.Next
  161. }
  162. // Terminate routing field with a "NULL" SRE.
  163. binary.BigEndian.PutUint32(buf[offset:offset+4], 0)
  164. }
  165. if g.AckPresent {
  166. binary.BigEndian.PutUint32(buf[offset:offset+4], g.Ack)
  167. offset += 4
  168. }
  169. if g.ChecksumPresent {
  170. if opts.ComputeChecksums {
  171. g.Checksum = tcpipChecksum(b.Bytes(), 0)
  172. }
  173. binary.BigEndian.PutUint16(buf[4:6], g.Checksum)
  174. }
  175. return nil
  176. }
  177. // CanDecode returns the set of layer types that this DecodingLayer can decode.
  178. func (g *GRE) CanDecode() gopacket.LayerClass {
  179. return LayerTypeGRE
  180. }
  181. // NextLayerType returns the layer type contained by this DecodingLayer.
  182. func (g *GRE) NextLayerType() gopacket.LayerType {
  183. return g.Protocol.LayerType()
  184. }
  185. func decodeGRE(data []byte, p gopacket.PacketBuilder) error {
  186. g := &GRE{}
  187. return decodingLayerDecoder(g, data, p)
  188. }