func main() { defer util.Run()() var handle *pcap.Handle var err error // Set up pcap packet capture if *fname != "" { log.Printf("Reading from pcap dump %q", *fname) handle, err = pcap.OpenOffline(*fname) } else { log.Printf("Starting capture on interface %q", *iface) handle, err = pcap.OpenLive(*iface, int32(*snaplen), true, pcap.BlockForever) } if err != nil { log.Fatal(err) } if err := handle.SetBPFFilter(*filter); err != nil { log.Fatal(err) } // Set up assembly streamFactory := &httpStreamFactory{} streamPool := tcpassembly.NewStreamPool(streamFactory) assembler := tcpassembly.NewAssembler(streamPool) log.Println("reading in packets") // Read in packets, pass to assembler. packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) packets := packetSource.Packets() ticker := time.Tick(time.Minute) for { select { case packet := <-packets: // A nil packet indicates the end of a pcap file. if packet == nil { return } if *logAllPackets { log.Println(packet) } if packet.NetworkLayer() == nil || packet.TransportLayer() == nil || packet.TransportLayer().LayerType() != layers.LayerTypeTCP { log.Println("Unusable packet") continue } tcp := packet.TransportLayer().(*layers.TCP) assembler.AssembleWithTimestamp(packet.NetworkLayer().NetworkFlow(), tcp, packet.Metadata().Timestamp) case <-ticker: // Every minute, flush connections that haven't seen activity in the past 2 minutes. assembler.FlushOlderThan(time.Now().Add(time.Minute * -2)) } } }
func (tap *Wiretap) capture(handle *pcap.Handle, channel chan gopacket.Packet) { defer handle.Close() src := gopacket.NewPacketSource(handle, handle.LinkType()) src.DecodeOptions = gopacket.NoCopy for { packet, err := src.NextPacket() if err == io.EOF { return } else if err == nil { channel <- packet } } }
//startCapture captures all packets on any interface for an unlimited duration. //Packets can be filtered by a BPF filter string. (E.g. tcp port 22) func capture(snaplen int32, quit chan bool, captureReady chan bool, pcapFile string) error { var handle *pcap.Handle var err error if pcapFile != "" { log.Println("Reading packet loss data from pcap-file:", pcapFile) handle, err = pcap.OpenOffline(pcapFile) } else { //https://godoc.org/code.google.com/p/gopacket/pcap //This might have been the culprit //Alternative to try: 250*time.Millisecond handle, err = pcap.OpenLive("any", snaplen, true, 250*time.Millisecond) } if err != nil { log.Println("Error while start capturing packets", err) return err } packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) captureReady <- true for { select { case packet := <-packetSource.Packets(): if packet != nil { if packet.Layer(layers.LayerTypeIPSecESP) != nil { putChannel(packet, ipSecChannel) } if packet.Layer(layers.LayerTypeICMPv4) != nil { putChannel(packet, icmpChannel) } } case <-quit: log.Println("Received quit message, stopping Listener.") return nil } } }