streaming

Media streaming and broadcast systems in Go
Log | Files | Refs | README | LICENSE

commit 5446ee9238512d767735753f9f435b42ae4df0cc
parent eaad0eae5c24e2cdf206d68dc8ee75d395ce944c
Author: Joshua Callary <joshuacallary@miraitechnologies.com.au>
Date:   Sat, 20 Jul 2024 09:08:31 +1000

pcap: implement decoding

Diffstat:
Apcap/parser.go | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apcap/parser_test.go | 34++++++++++++++++++++++++++++++++++
Apcap/testing/srt_capture_test.pcap | 0
3 files changed, 110 insertions(+), 0 deletions(-)

diff --git a/pcap/parser.go b/pcap/parser.go @@ -0,0 +1,76 @@ +package pcap + +import ( + "encoding/binary" + "errors" + "io" +) + +type GlobalHeader struct { + MagicNumber uint32 + VersionMajor uint16 + VersionMinor uint16 + ThisZone int32 + SigFigs uint32 + SnapLen uint32 + Network uint32 +} + +type Header struct { + TsSec uint32 + TsUsec uint32 + InclLen uint32 + OrigLen uint32 +} + +type Packet struct { + Header Header + Data []byte +} + +type File struct { + Header GlobalHeader + Packets []Packet +} + +func decode(reader io.Reader) (*File, error) { + var header GlobalHeader + err := binary.Read(reader, binary.LittleEndian, &header) + + if err != nil { + return nil, err + } + + if header.MagicNumber != 0xa1b2c3d4 && header.MagicNumber != 0xd4c3b2a1 { + return nil, errors.New("invalid magic number in pcap file") + } + + var packets []Packet + + for { + var header Header + err := binary.Read(reader, binary.LittleEndian, &header) + if err == io.EOF { + break + } + if err != nil { + return nil, err + } + + data := make([]byte, header.InclLen) + _, err = io.ReadFull(reader, data) + if err != nil { + return nil, err + } + + packets = append(packets, Packet{ + Header: header, + Data: data, + }) + } + + return &File{ + Header: header, + Packets: packets, + }, nil +} diff --git a/pcap/parser_test.go b/pcap/parser_test.go @@ -0,0 +1,34 @@ +package pcap + +import ( + "fmt" + "os" + "testing" +) + +func TestReadFile(t *testing.T) { + filePath := "testing/srt_capture_test.pcap" + + file, err := os.Open(filePath) + if err != nil { + t.Fatal("Failed to open file") + } + defer file.Close() + + pcapFile, err := decode(file) + if err != nil { + t.Fatalf("Failed to read PCAP file: %v", err) + } + + if len(pcapFile.Packets) == 0 { + t.Fatal("Should be at least one packet but there is 0") + } + + fmt.Printf("PCAP Header: %+v\n", pcapFile.Header) + + for i, packet := range pcapFile.Packets { + fmt.Printf("Packet %d: %+v\n", i, packet.Header) + + fmt.Printf("Data %d: %x\n", i, packet.Data) + } +} diff --git a/pcap/testing/srt_capture_test.pcap b/pcap/testing/srt_capture_test.pcap Binary files differ.