gre.go 5.0 KB

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