Skip to content

Commit

Permalink
Merge pull request #3 from bi-zone/merge-upstream
Browse files Browse the repository at this point in the history
Merge upstream
  • Loading branch information
yalegko authored May 30, 2024
2 parents e6b6244 + 8e9a843 commit 712bb3f
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 5 deletions.
15 changes: 11 additions & 4 deletions afpacket/afpacket.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// that can be found in the LICENSE file in the root of the source
// tree.

//go:build linux
// +build linux

// Package afpacket provides Go bindings for MMap'd AF_PACKET socket reading.
Expand Down Expand Up @@ -268,6 +269,11 @@ func (h *TPacket) SetBPF(filter []bpf.RawInstruction) error {
return unix.SetsockoptSockFprog(h.fd, unix.SOL_SOCKET, unix.SO_ATTACH_FILTER, &p)
}

// attach ebpf filter to af-packet
func (h *TPacket) SetEBPF(progFd int32) error {
return unix.SetsockoptInt(h.fd, unix.SOL_SOCKET, unix.SO_ATTACH_BPF, int(progFd))
}

func (h *TPacket) releaseCurrentPacket() error {
h.current.clearStatus()
h.offset++
Expand All @@ -282,10 +288,11 @@ func (h *TPacket) releaseCurrentPacket() error {
// to old bytes when using ZeroCopyReadPacketData... if you need to keep data past
// the next time you call ZeroCopyReadPacketData, use ReadPacketData, which copies
// the bytes into a new buffer for you.
// tp, _ := NewTPacket(...)
// data1, _, _ := tp.ZeroCopyReadPacketData()
// // do everything you want with data1 here, copying bytes out of it if you'd like to keep them around.
// data2, _, _ := tp.ZeroCopyReadPacketData() // invalidates bytes in data1
//
// tp, _ := NewTPacket(...)
// data1, _, _ := tp.ZeroCopyReadPacketData()
// // do everything you want with data1 here, copying bytes out of it if you'd like to keep them around.
// data2, _, _ := tp.ZeroCopyReadPacketData() // invalidates bytes in data1
func (h *TPacket) ZeroCopyReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) {
h.mu.Lock()
retry:
Expand Down
8 changes: 8 additions & 0 deletions layers/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,10 @@ func (q *DNSQuestion) decode(data []byte, offset int, df gopacket.DecodeFeedback
return 0, err
}

if len(data) < endq+4 {
return 0, errors.New("DNS question too small")
}

q.Name = name
q.Type = DNSType(binary.BigEndian.Uint16(data[endq : endq+2]))
q.Class = DNSClass(binary.BigEndian.Uint16(data[endq+2 : endq+4]))
Expand Down Expand Up @@ -709,6 +713,10 @@ func (rr *DNSResourceRecord) decode(data []byte, offset int, df gopacket.DecodeF
return 0, err
}

if len(data) < endq+10 {
return 0, errors.New("DNS record too small")
}

rr.Name = name
rr.Type = DNSType(binary.BigEndian.Uint16(data[endq : endq+2]))
rr.Class = DNSClass(binary.BigEndian.Uint16(data[endq+2 : endq+4]))
Expand Down
7 changes: 7 additions & 0 deletions layers/dns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ import (
"github.com/google/gopacket"
)

func FuzzDecodeFromBytes(f *testing.F) {
f.Fuzz(func(t *testing.T, bytes []byte) {
dns := DNS{}
dns.DecodeFromBytes(bytes, gopacket.NilDecodeFeedback)
})
}

// it have a layer like that:
// name: xxx.com
// type: CNAME
Expand Down
57 changes: 57 additions & 0 deletions layers/geneve.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package layers
import (
"encoding/binary"
"errors"
"fmt"

"github.com/google/gopacket"
)
Expand Down Expand Up @@ -119,3 +120,59 @@ func decodeGeneve(data []byte, p gopacket.PacketBuilder) error {
gn := &Geneve{}
return decodingLayerDecoder(gn, data, p)
}

// SerializeTo writes the serialized form of this layer into the
// SerializationBuffer, implementing gopacket.SerializableLayer.
// See the docs for gopacket.SerializableLayer for more info.
func (gn *Geneve) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
plen := int(gn.OptionsLength + 8)
bytes, err := b.PrependBytes(plen)
if err != nil {
return err
}

// PrependBytes does not guarantee that bytes are zeroed. Setting flags via OR requires that they start off at zero
bytes[0] = 0
bytes[1] = 0

// Construct Geneve

bytes[0] |= gn.Version << 6
bytes[0] |= ((gn.OptionsLength >> 2) & 0x3f)

if gn.OAMPacket {
bytes[1] |= 0x80
}

if gn.CriticalOption {
bytes[1] |= 0x40
}

binary.BigEndian.PutUint16(bytes[2:4], uint16(gn.Protocol))

if gn.VNI >= 1<<24 {
return fmt.Errorf("Virtual Network Identifier = %x exceeds max for 24-bit uint", gn.VNI)
}
binary.BigEndian.PutUint32(bytes[4:8], gn.VNI<<8)

// Construct Options

offset, _ := uint8(8), int32(gn.OptionsLength)
for _, o := range gn.Options {
binary.BigEndian.PutUint16(bytes[offset:(offset+2)], uint16(o.Class))

offset += 2
bytes[offset] = o.Type

offset += 1
bytes[offset] |= o.Flags << 5
bytes[offset] |= ((o.Length - 4) >> 2) & 0x1f

offset += 1
copy(bytes[offset:(offset+o.Length-4)], o.Data)

offset += o.Length - 4
}

return nil
}
38 changes: 37 additions & 1 deletion layers/geneve_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ func TestDecodeGeneve3(t *testing.T) {
Protocol: EthernetTypeTransparentEthernetBridging,
VNI: 0xa,
Options: []*GeneveOption{
&GeneveOption{
{
Class: 0x0,
Type: 0x80,
Length: 8,
Expand All @@ -155,3 +155,39 @@ func BenchmarkDecodeGeneve1(b *testing.B) {
gopacket.NewPacket(testPacketGeneve1, LinkTypeEthernet, gopacket.NoCopy)
}
}

func TestIsomorphicPacketGeneve(t *testing.T) {
gn := &Geneve{
Version: 0x0,
OptionsLength: 0x14,
OAMPacket: false,
CriticalOption: true,
Protocol: EthernetTypeTransparentEthernetBridging,
VNI: 0xa,
Options: []*GeneveOption{
{
Class: 0x0,
Type: 0x80,
Length: 12,
Data: []byte{0, 0, 0, 0, 0, 0, 0, 0xc},
},
{
Class: 0x0,
Type: 0x80,
Length: 8,
Data: []byte{0, 0, 0, 0xc},
},
},
}

b := gopacket.NewSerializeBuffer()
gn.SerializeTo(b, gopacket.SerializeOptions{})

p := gopacket.NewPacket(b.Bytes(), gopacket.DecodeFunc(decodeGeneve), gopacket.Default)
gnTranslated := p.Layer(LayerTypeGeneve).(*Geneve)
gnTranslated.BaseLayer = BaseLayer{}

if !reflect.DeepEqual(gn, gnTranslated) {
t.Errorf("VXLAN isomorph mismatch, \nwant %#v\ngot %#v\n", gn, gnTranslated)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("0000000\x10\x10\x00\x01\x01\x01\x01\x01\x01\x00")
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("000000000000\x00")
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("01000\x10\x10\xdfd\x01\x01\x01\x00d\x01\x01\x01\x00")
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("0000\x00\x00000000\x010\x000")

0 comments on commit 712bb3f

Please sign in to comment.