commit 5446ee9238512d767735753f9f435b42ae4df0cc
parent eaad0eae5c24e2cdf206d68dc8ee75d395ce944c
Author: Joshua Callary <joshuacallary@miraitechnologies.com.au>
Date: Sat, 20 Jul 2024 09:08:31 +1000
pcap: implement decoding
Diffstat:
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.