Skip to content

Commit

Permalink
Fix GRE header decoding
Browse files Browse the repository at this point in the history
- check if the optional fields exist before consuming data
- `Routing` field is a list of SREs
  • Loading branch information
kaorimatz committed May 4, 2015
1 parent 09bce8a commit 6b72c50
Showing 1 changed file with 32 additions and 19 deletions.
51 changes: 32 additions & 19 deletions layers/gre.go
Expand Up @@ -19,12 +19,15 @@ type GRE struct {
Protocol EthernetType
Checksum, Offset uint16
Key, Seq uint32
*GRERouting
GRERouting GRERouting
}

// GRERouting is GRE routing information, present if the RoutingPresent flag is
// set.
type GRERouting struct {
type GRERouting []*GRESourceRouteEntry

// GRESourceRouteEntry is GRE routing information entry.
type GRESourceRouteEntry struct {
AddressFamily uint16
SREOffset, SRELength uint8
RoutingInformation []byte
Expand All @@ -44,26 +47,36 @@ func (g *GRE) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
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:]
offset := 4
if g.ChecksumPresent || g.RoutingPresent {
g.Checksum = binary.BigEndian.Uint16(data[offset : offset+2])
g.Offset = binary.BigEndian.Uint16(data[offset+2 : offset+4])
offset += 4
}
if g.KeyPresent {
g.Key = binary.BigEndian.Uint32(data[offset : offset+4])
offset += 4
}
if g.SeqPresent {
g.Seq = binary.BigEndian.Uint32(data[offset : offset+4])
offset += 4
}
if g.RoutingPresent {
g.GRERouting = &GRERouting{
AddressFamily: binary.BigEndian.Uint16(rData[:2]),
SREOffset: rData[2],
SRELength: rData[3],
for {
sre := &GRESourceRouteEntry{
AddressFamily: binary.BigEndian.Uint16(data[offset : offset+2]),
SREOffset: data[offset+2],
SRELength: data[offset+3],
}
sre.RoutingInformation = data[offset+4 : offset+4+int(sre.SRELength)]
offset += 4 + int(sre.SRELength)
if sre.AddressFamily == 0 && sre.SRELength == 0 {
break
}
g.GRERouting = append(g.GRERouting, sre)
}
end := g.SRELength + 4
g.RoutingInformation = rData[4:end]
g.Contents = data[:16+end]
g.Payload = data[16+end:]
} else {
g.GRERouting = nil
}
g.BaseLayer = BaseLayer{data[:offset], data[offset:]}
return nil
}

Expand Down

0 comments on commit 6b72c50

Please sign in to comment.