Skip to content

Instantly share code, notes, and snippets.

@WGH-
Created March 6, 2018 16:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save WGH-/ddd6390f37ceb7455e4f22b4ee5eeb9f to your computer and use it in GitHub Desktop.
Save WGH-/ddd6390f37ceb7455e4f22b4ee5eeb9f to your computer and use it in GitHub Desktop.
package main
import (
"bufio"
"log"
"os"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcapgo"
"github.com/google/gopacket/reassembly"
)
func NewAssembler() *reassembly.Assembler {
streamFactory := &myFactory{}
streamPool := reassembly.NewStreamPool(streamFactory)
return reassembly.NewAssembler(streamPool)
}
type myFactory struct {
counter int64
}
func (f *myFactory) New(netFlow, tcpFlow gopacket.Flow, tcp *layers.TCP, ac reassembly.AssemblerContext) reassembly.Stream {
f.counter += 1
fsmOptions := reassembly.TCPSimpleFSMOptions{
SupportMissingEstablishment: false,
}
s := &myStream{
i: f.counter,
tcpstate: reassembly.NewTCPSimpleFSM(fsmOptions),
}
log.Printf("stream #%d: (created)", s.i)
return s
}
type myStream struct {
i int64
tcpstate *reassembly.TCPSimpleFSM
}
func (s *myStream) Accept(tcp *layers.TCP, ci gopacket.CaptureInfo, dir reassembly.TCPFlowDirection, ackSeq reassembly.Sequence, start *bool, ac reassembly.AssemblerContext) bool {
if !s.tcpstate.CheckState(tcp, dir) {
log.Printf("stream #%d: Accept rejected by FSM", s.i)
return false
}
log.Printf("stream #%d: Accept", s.i)
return true
}
func (s *myStream) ReassembledSG(sg reassembly.ScatterGather, ac reassembly.AssemblerContext) {
log.Printf("stream #%d: ReassembledSG", s.i)
}
func (s *myStream) ReassemblyComplete(ac reassembly.AssemblerContext) bool {
log.Printf("stream #%d: ReassemblyComplete", s.i)
return false // XXX?
}
type Context struct {
CaptureInfo gopacket.CaptureInfo
}
func (c *Context) GetCaptureInfo() gopacket.CaptureInfo {
return c.CaptureInfo
}
func main() {
file, err := os.Open(os.Args[1])
if err != nil {
log.Fatal(err)
}
pcap, err := pcapgo.NewReader(bufio.NewReader(file))
if err != nil {
log.Fatal(err)
}
packetSource := gopacket.NewPacketSource(pcap, pcap.LinkType())
packets := packetSource.Packets()
assembler := NewAssembler()
var packetNo int64
packetNo = 1
for packet := range packets {
if packet.NetworkLayer() == nil || packet.TransportLayer() == nil || packet.TransportLayer().LayerType() != layers.LayerTypeTCP {
continue
}
tcp := packet.TransportLayer().(*layers.TCP)
log.Printf("packet %d: calling AssembleWithTimestamp()", packetNo)
packetNo++
assembler.AssembleWithContext(packet.NetworkLayer().NetworkFlow(), tcp, &Context{packet.Metadata().CaptureInfo})
}
log.Print("calling FlushAll")
assembler.FlushAll()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment