Skip to content

Commit 2f515f1

Browse files
committed
Add ability to concat finite packet sources.
1 parent 58db438 commit 2f515f1

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

packet.go

+25
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,31 @@ type PacketDataSource interface {
684684
ReadPacketData() (data []byte, ci CaptureInfo, err error)
685685
}
686686

687+
// ConcatFinitePacketDataSources returns a PacketDataSource that wraps a set
688+
// of internal PacketDataSources, each of which will stop with io.EOF after
689+
// reading a finite number of packets. The returned PacketDataSource will
690+
// return all packets from the first finite source, followed by all packets from
691+
// the second, etc. Once all finite sources have returned io.EOF, the returned
692+
// source will as well.
693+
func ConcatFinitePacketDataSources(pds ...PacketDataSource) PacketDataSource {
694+
c := concat(pds)
695+
return &c
696+
}
697+
698+
type concat []PacketDataSource
699+
700+
func (c *concat) ReadPacketData() (data []byte, ci CaptureInfo, err error) {
701+
for len(*c) > 0 {
702+
data, ci, err = (*c)[0].ReadPacketData()
703+
if err == io.EOF {
704+
*c = (*c)[1:]
705+
continue
706+
}
707+
return
708+
}
709+
return nil, CaptureInfo{}, io.EOF
710+
}
711+
687712
// ZeroCopyPacketDataSource is an interface to pull packet data from sources
688713
// that allow data to be returned without copying to a user-controlled buffer.
689714
// It's very similar to PacketDataSource, except that the caller must be more

packet_test.go

+34
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
package gopacket
88

99
import (
10+
"io"
1011
"reflect"
1112
"testing"
1213
)
@@ -26,3 +27,36 @@ func TestDumpEmbedded(t *testing.T) {
2627
t.Errorf("embedded dump mismatch:\n got: %v\n want: %v", got, want)
2728
}
2829
}
30+
31+
type singlePacketSource [1][]byte
32+
33+
func (s *singlePacketSource) ReadPacketData() ([]byte, CaptureInfo, error) {
34+
if (*s)[0] == nil {
35+
return nil, CaptureInfo{}, io.EOF
36+
}
37+
out := (*s)[0]
38+
(*s)[0] = nil
39+
return out, CaptureInfo{}, nil
40+
}
41+
42+
func TestConcatPacketSources(t *testing.T) {
43+
sourceA := &singlePacketSource{[]byte{1}}
44+
sourceB := &singlePacketSource{[]byte{2}}
45+
sourceC := &singlePacketSource{[]byte{3}}
46+
concat := ConcatFinitePacketDataSources(sourceA, sourceB, sourceC)
47+
a, _, err := concat.ReadPacketData()
48+
if err != nil || len(a) != 1 || a[0] != 1 {
49+
t.Errorf("expected [1], got %v/%v", a, err)
50+
}
51+
b, _, err := concat.ReadPacketData()
52+
if err != nil || len(b) != 1 || b[0] != 2 {
53+
t.Errorf("expected [2], got %v/%v", b, err)
54+
}
55+
c, _, err := concat.ReadPacketData()
56+
if err != nil || len(c) != 1 || c[0] != 3 {
57+
t.Errorf("expected [3], got %v/%v", c, err)
58+
}
59+
if _, _, err := concat.ReadPacketData(); err != io.EOF {
60+
t.Errorf("expected io.EOF, got %v", err)
61+
}
62+
}

0 commit comments

Comments
 (0)