forked from elastic/beats
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gre.go
83 lines (74 loc) · 2.58 KB
/
gre.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// Copyright 2012 Google, Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree.
package layers
import (
"encoding/binary"
"github.com/tsg/gopacket"
)
// GRE is a Generic Routing Encapsulation header.
type GRE struct {
BaseLayer
ChecksumPresent, RoutingPresent, KeyPresent, SeqPresent, StrictSourceRoute bool
RecursionControl, Flags, Version uint8
Protocol EthernetType
Checksum, Offset uint16
Key, Seq uint32
*GRERouting
}
// GRERouting is GRE routing information, present if the RoutingPresent flag is
// set.
type GRERouting struct {
AddressFamily uint16
SREOffset, SRELength uint8
RoutingInformation []byte
}
// LayerType returns gopacket.LayerTypeGRE.
func (g *GRE) LayerType() gopacket.LayerType { return LayerTypeGRE }
// DecodeFromBytes decodes the given bytes into this layer.
func (g *GRE) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
g.ChecksumPresent = data[0]&0x80 != 0
g.RoutingPresent = data[0]&0x40 != 0
g.KeyPresent = data[0]&0x20 != 0
g.SeqPresent = data[0]&0x10 != 0
g.StrictSourceRoute = data[0]&0x08 != 0
g.RecursionControl = data[0] & 0x7
g.Flags = data[1] >> 3
g.Version = data[1] & 0x7
g.Protocol = EthernetType(binary.BigEndian.Uint16(data[2:4]))
g.Checksum = binary.BigEndian.Uint16(data[4:6])
g.Offset = binary.BigEndian.Uint16(data[6:8])
g.Key = binary.BigEndian.Uint32(data[8:12])
g.Seq = binary.BigEndian.Uint32(data[12:16])
g.BaseLayer = BaseLayer{data[:16], data[16:]}
// reset data to point to after the main gre header
rData := data[16:]
if g.RoutingPresent {
g.GRERouting = &GRERouting{
AddressFamily: binary.BigEndian.Uint16(rData[:2]),
SREOffset: rData[2],
SRELength: rData[3],
}
end := g.SRELength + 4
g.RoutingInformation = rData[4:end]
g.Contents = data[:16+end]
g.Payload = data[16+end:]
} else {
g.GRERouting = nil
}
return nil
}
// CanDecode returns the set of layer types that this DecodingLayer can decode.
func (g *GRE) CanDecode() gopacket.LayerClass {
return LayerTypeGRE
}
// NextLayerType returns the layer type contained by this DecodingLayer.
func (g *GRE) NextLayerType() gopacket.LayerType {
return g.Protocol.LayerType()
}
func decodeGRE(data []byte, p gopacket.PacketBuilder) error {
g := &GRE{}
return decodingLayerDecoder(g, data, p)
}