From cc07f5a72325424ebc1410862d898cba75c34aaa Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Thu, 24 Sep 2020 20:41:32 -0600 Subject: [PATCH] Add a big pcap file for a new test --- hk_test.go | 179 +++++++++++++++++++++++++++++++++++++++++++++++ testdata/hk.pcap | Bin 0 -> 21124 bytes 2 files changed, 179 insertions(+) create mode 100644 hk_test.go create mode 100644 testdata/hk.pcap diff --git a/hk_test.go b/hk_test.go new file mode 100644 index 0000000..04911aa --- /dev/null +++ b/hk_test.go @@ -0,0 +1,179 @@ +// hk_test is a start at a decoder I was writing, which exhibited some problems. +// It also illustrates what a real decoder might look like. + +package netshovel + +import ( + "fmt" + "io" + "log" + "strings" + "sync" + "testing" + + "github.com/google/gopacket" + "github.com/google/gopacket/tcpassembly" +) + +var wg sync.WaitGroup + +// HKStreamFactory generates HKStreams. +type HKStreamFactory struct { + err *error +} + +// New returns a new HKStream. +func (f *HKStreamFactory) New(net, transport gopacket.Flow) tcpassembly.Stream { + stream := &HKStream{ + Stream: NewStream(net, transport), + err: f.err, + } + wg.Add(1) + go stream.Decode(&wg) + + return stream +} + +// HKStream represents half of a TCP Stream. +type HKStream struct { + *Stream + err *error +} + +func (stream HKStream) Read(length int) (Utterance, error) { + u, err := stream.Stream.Read(length) + return u, err +} + +// DisplayUtterance prints an unparsed TCP utterance +func (stream HKStream) DisplayUtterance(u Utterance) { + fmt.Printf("Unparsed %v:%v → %v:%v\n", + stream.Net.Src().String(), stream.Transport.Src().String(), + stream.Net.Dst().String(), stream.Transport.Dst().String(), + ) + fmt.Println(u.Data.Hexdump()) +} + +// Display prints as much about an HKPacket as we are able to determine. +func (stream HKStream) Display(pkt HKPacket) { + out := new(strings.Builder) + + fmt.Fprintf(out, "HK %v:%v → %v:%v\n", + stream.Net.Src().String(), stream.Transport.Src().String(), + stream.Net.Dst().String(), stream.Transport.Dst().String(), + ) + out.WriteString(pkt.Describe()) + fmt.Println(out.String()) +} + +// Decode decodes all data from the stream. +func (stream HKStream) Decode(wg *sync.WaitGroup) { + defer wg.Done() + for { + utterance, err := stream.Read(2) + if err == io.EOF { + return + } else if err != nil { + log.Println(err) + return + } + + // Was it actually HK? + if utterance.Data.String("DROP") != "HK" { + u, err := stream.Read(-1) + if err != nil { + log.Println(err) + return + } + + if utterance.When != u.When { + stream.DisplayUtterance(utterance) + utterance = u + *stream.err = fmt.Errorf("Short length on non-HK packet, and a different utterance was returned") + } else { + utterance.Data = utterance.Data.Append(u.Data) + } + if utterance.Data.Length() < 10 { + *stream.err = fmt.Errorf("Short length on non-HK packet") + return + } + stream.DisplayUtterance(utterance) + continue + } + + pkt := NewHKPacket(utterance) + if err := pkt.Decode(stream); err != nil { + log.Println(err) + return + } + stream.Display(pkt) + } +} + +// NewHKPacket returns a shiny new HKPacket. +func NewHKPacket(u Utterance) HKPacket { + pkt := HKPacket{ + Packet: NewPacket(), + } + pkt.Payload = u.Data + pkt.When = u.When + return pkt +} + +// HKPacket is a single HK packet. +type HKPacket struct { + Packet +} + +// Decode from a readable +func (pkt *HKPacket) Decode(stream HKStream) error { + header, err := stream.Read(9) + if err != nil { + return err + } + pkt.Payload = header.Data + + unknown, _ := pkt.Uint32BE("unknown") + length, _ := pkt.Uint32BE("length") + opcode, _ := pkt.Uint8("opcode") + pkt.Opcode = int(opcode) + + if unknown != 0 { + return fmt.Errorf("unknown header was actually %d", unknown) + } + if length > 100 { + return fmt.Errorf("Length too big: %d", length) + } + + body, err := stream.Read(int(length - 9 - 2)) + if err != nil { + return err + } + pkt.Payload = body.Data + + subcode, _ := pkt.Uint8("subcode") + if subcode != 0 { + return fmt.Errorf("Subcode not zero: %d", subcode) + } + pkt.SetString("Payload", pkt.Payload.String("DROP")) + + switch pkt.Opcode { + case 7: + pkt.Description = "Keepalive" + } + + return nil +} + +func TestHK(t *testing.T) { + factory := HKStreamFactory{err: new(error)} + streamPool := tcpassembly.NewStreamPool(&factory) + assembler := tcpassembly.NewAssembler(streamPool) + ShovelFile("testdata/hk.pcap", assembler) + assembler.FlushAll() + wg.Wait() + + if *factory.err != nil { + t.Error(*factory.err) + } +} diff --git a/testdata/hk.pcap b/testdata/hk.pcap new file mode 100644 index 0000000000000000000000000000000000000000..803751857f60a0ad5dc23c00a3b74bbbb7da0da5 GIT binary patch literal 21124 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 Ufx#0=PlWKafag3tZ~Rr~-()YVxBvhE literal 0 HcmV?d00001