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 (sniffer *SnifferSetup) Reopen() error { var err error if sniffer.config.Type != "pcap" || sniffer.config.File == "" { return fmt.Errorf("Reopen is only possible for files") } sniffer.pcapHandle.Close() sniffer.pcapHandle, err = pcap.OpenOffline(sniffer.config.File) if err != nil { return err } sniffer.DataSource = gopacket.PacketDataSource(sniffer.pcapHandle) return nil }
func main() { defer util.Run()() var handle *pcap.Handle var err error if *fname != "" { if handle, err = pcap.OpenOffline(*fname); err != nil { log.Fatal("PCAP OpenOffline error:", err) } } else { // This is a little complicated because we want to allow all possible options // for creating the packet capture handle... instead of all this you can // just call pcap.OpenLive if you want a simple handle. inactive, err := pcap.NewInactiveHandle(*iface) if err != nil { log.Fatal("could not create: %v", err) } defer inactive.CleanUp() if err = inactive.SetSnapLen(*snaplen); err != nil { log.Fatal("could not set snap length: %v", err) } else if err = inactive.SetPromisc(*promisc); err != nil { log.Fatal("could not set promisc mode: %v", err) } else if err = inactive.SetTimeout(time.Second); err != nil { log.Fatal("could not set timeout: %v", err) } if *tstype != "" { if t, err := pcap.TimestampSourceFromString(*tstype); err != nil { log.Fatalf("Supported timestamp types: %v", inactive.SupportedTimestamps()) } else if err := inactive.SetTimestampSource(t); err != nil { log.Fatalf("Supported timestamp types: %v", inactive.SupportedTimestamps()) } } if handle, err = inactive.Activate(); err != nil { log.Fatal("PCAP Activate error:", err) } defer handle.Close() if len(flag.Args()) > 0 { bpffilter := strings.Join(flag.Args(), " ") fmt.Fprintf(os.Stderr, "Using BPF filter %q\n", bpffilter) if err = handle.SetBPFFilter(bpffilter); err != nil { log.Fatal("BPF filter error:", err) } } } dumpcommand.Run(handle) }
func (sniffer *SnifferSetup) setFromConfig(config *config.InterfacesConfig) error { var err error sniffer.config = config if len(sniffer.config.File) > 0 { logp.Debug("sniffer", "Reading from file: %s", sniffer.config.File) // we read file with the pcap provider sniffer.config.Type = "pcap" } // set defaults if len(sniffer.config.Device) == 0 { sniffer.config.Device = "any" } if index, err := strconv.Atoi(sniffer.config.Device); err == nil { // Device is numeric devices, err := ListDeviceNames() if err != nil { return fmt.Errorf("Error getting devices list: %v", err) } sniffer.config.Device, err = deviceNameFromIndex(index, devices) if err != nil { return fmt.Errorf("Couldn't understand device index %d: %v", index, err) } logp.Info("Resolved device index %d to device: %s", index, sniffer.config.Device) } if sniffer.config.Snaplen == 0 { sniffer.config.Snaplen = 65535 } if sniffer.config.Type == "autodetect" || sniffer.config.Type == "" { sniffer.config.Type = "pcap" } logp.Debug("sniffer", "Sniffer type: %s device: %s", sniffer.config.Type, sniffer.config.Device) switch sniffer.config.Type { case "pcap": if len(sniffer.config.File) > 0 { sniffer.pcapHandle, err = pcap.OpenOffline(sniffer.config.File) if err != nil { return err } } else { sniffer.pcapHandle, err = pcap.OpenLive( sniffer.config.Device, int32(sniffer.config.Snaplen), true, 500*time.Millisecond) if err != nil { return err } err = sniffer.pcapHandle.SetBPFFilter(sniffer.config.Bpf_filter) if err != nil { return err } } sniffer.DataSource = gopacket.PacketDataSource(sniffer.pcapHandle) case "af_packet": if sniffer.config.Buffer_size_mb == 0 { sniffer.config.Buffer_size_mb = 24 } frame_size, block_size, num_blocks, err := afpacketComputeSize( sniffer.config.Buffer_size_mb, sniffer.config.Snaplen, os.Getpagesize()) if err != nil { return err } sniffer.afpacketHandle, err = NewAfpacketHandle( sniffer.config.Device, frame_size, block_size, num_blocks, 500*time.Millisecond) if err != nil { return err } err = sniffer.afpacketHandle.SetBPFFilter(sniffer.config.Bpf_filter) if err != nil { return fmt.Errorf("SetBPFFilter failed: %s", err) } sniffer.DataSource = gopacket.PacketDataSource(sniffer.afpacketHandle) case "pfring": sniffer.pfringHandle, err = NewPfringHandle( sniffer.config.Device, sniffer.config.Snaplen, true) if err != nil { return err } err = sniffer.pfringHandle.SetBPFFilter(sniffer.config.Bpf_filter) if err != nil { return fmt.Errorf("SetBPFFilter failed: %s", err) } err = sniffer.pfringHandle.Enable() if err != nil { return fmt.Errorf("Enable failed: %s", err) } sniffer.DataSource = gopacket.PacketDataSource(sniffer.pfringHandle) default: return fmt.Errorf("Unknown sniffer type: %s", sniffer.config.Type) } return nil }
func (sniffer *SnifferSetup) setFromConfig(config *config.InterfacesConfig) error { var err error sniffer.config = config if len(sniffer.config.File) > 0 { logp.Debug("sniffer", "Reading from file: %s", sniffer.config.File) // we read file with the pcap provider sniffer.config.Type = "pcap" } // set defaults if len(sniffer.config.Device) == 0 { sniffer.config.Device = "any" } if len(sniffer.config.Devices) == 0 { // 'devices' not set but 'device' is set. For backwards compatibility, // use the one configured device if len(sniffer.config.Device) > 0 { sniffer.config.Devices = []string{sniffer.config.Device} } } if sniffer.config.Snaplen == 0 { sniffer.config.Snaplen = 65535 } if sniffer.config.Type == "autodetect" || sniffer.config.Type == "" { sniffer.config.Type = "pcap" } logp.Debug("sniffer", "Sniffer type: %s devices: %s", sniffer.config.Type, sniffer.config.Devices) switch sniffer.config.Type { case "pcap": if len(sniffer.config.File) > 0 { sniffer.pcapHandle, err = pcap.OpenOffline(sniffer.config.File) if err != nil { return err } } else { if len(sniffer.config.Devices) > 1 { return fmt.Errorf("Pcap sniffer only supports one device. You can use 'any' if you want") } sniffer.pcapHandle, err = pcap.OpenLive( sniffer.config.Devices[0], int32(sniffer.config.Snaplen), true, 500*time.Millisecond) if err != nil { return err } err = sniffer.pcapHandle.SetBPFFilter(sniffer.config.Bpf_filter) if err != nil { return err } } sniffer.DataSource = gopacket.PacketDataSource(sniffer.pcapHandle) case "af_packet": if sniffer.config.Buffer_size_mb == 0 { sniffer.config.Buffer_size_mb = 24 } if len(sniffer.config.Devices) > 1 { return fmt.Errorf("Afpacket sniffer only supports one device. You can use 'any' if you want") } frame_size, block_size, num_blocks, err := afpacketComputeSize( sniffer.config.Buffer_size_mb, sniffer.config.Snaplen, os.Getpagesize()) if err != nil { return err } sniffer.afpacketHandle, err = NewAfpacketHandle( sniffer.config.Devices[0], frame_size, block_size, num_blocks, 500*time.Millisecond) if err != nil { return err } err = sniffer.afpacketHandle.SetBPFFilter(sniffer.config.Bpf_filter) if err != nil { return fmt.Errorf("SetBPFFilter failed: %s", err) } sniffer.DataSource = gopacket.PacketDataSource(sniffer.afpacketHandle) case "pfring": if len(sniffer.config.Devices) > 1 { return fmt.Errorf("Afpacket sniffer only supports one device. You can use 'any' if you want") } sniffer.pfringHandle, err = NewPfringHandle( sniffer.config.Devices[0], sniffer.config.Snaplen, true) if err != nil { return err } err = sniffer.pfringHandle.SetBPFFilter(sniffer.config.Bpf_filter) if err != nil { return fmt.Errorf("SetBPFFilter failed: %s", err) } err = sniffer.pfringHandle.Enable() if err != nil { return fmt.Errorf("Enable failed: %s", err) } sniffer.DataSource = gopacket.PacketDataSource(sniffer.pfringHandle) default: return fmt.Errorf("Unknown sniffer type: %s", sniffer.config.Type) } return nil }
func main() { flag.Parse() filename := os.TempDir() + string(os.PathSeparator) + "gopacket_benchmark.pcap" if _, err := os.Stat(filename); err != nil { // This URL points to a publicly available packet data set from a DARPA // intrusion detection evaluation. See // http://www.ll.mit.edu/mission/communications/cyber/CSTcorpora/ideval/data/1999/training/week1/index.html // for more details. fmt.Println("Local pcap file", filename, "doesn't exist, reading from", *url) if resp, err := http.Get(*url); err != nil { panic(err) } else if out, err := os.Create(filename); err != nil { panic(err) } else if gz, err := gzip.NewReader(resp.Body); err != nil { panic(err) } else if n, err := io.Copy(out, gz); err != nil { panic(err) } else if err := gz.Close(); err != nil { panic(err) } else if err := out.Close(); err != nil { panic(err) } else { fmt.Println("Successfully read", n, "bytes from url, unzipped to local storage") } } fmt.Println("Reading file once through to hopefully cache most of it") if f, err := os.Open(filename); err != nil { panic(err) } else if n, err := io.Copy(ioutil.Discard, f); err != nil { panic(err) } else if err := f.Close(); err != nil { panic(err) } else { fmt.Println("Read in file", filename, ", total of", n, "bytes") } if *cpuProfile != "" { if cpu, err := os.Create(*cpuProfile); err != nil { panic(err) } else if err := pprof.StartCPUProfile(cpu); err != nil { panic(err) } else { defer func() { pprof.StopCPUProfile() cpu.Close() }() } } var packetDataSource *BufferPacketSource var packetSource *gopacket.PacketSource fmt.Printf("Opening file %q for read\n", filename) if h, err := pcap.OpenOffline(filename); err != nil { panic(err) } else { fmt.Println("Reading all packets into memory with BufferPacketSource.") start := time.Now() packetDataSource = NewBufferPacketSource(h) duration := time.Since(start) fmt.Printf("Time to read packet data into memory from file: %v\n", duration) packetSource = gopacket.NewPacketSource(packetDataSource, h.LinkType()) packetSource.DecodeOptions.Lazy = *decodeLazy packetSource.DecodeOptions.NoCopy = *decodeNoCopy } fmt.Println() for i := 0; i < *repeat; i++ { packetDataSource.Reset() fmt.Printf("Benchmarking decode %d/%d\n", i+1, *repeat) benchmarkPacketDecode(packetSource) } fmt.Println() for i := 0; i < *repeat; i++ { packetDataSource.Reset() fmt.Printf("Benchmarking decoding layer parser %d/%d\n", i+1, *repeat) benchmarkLayerDecode(packetDataSource, false) } fmt.Println() for i := 0; i < *repeat; i++ { packetDataSource.Reset() fmt.Printf("Benchmarking decoding layer parser with assembly %d/%d\n", i+1, *repeat) benchmarkLayerDecode(packetDataSource, true) } }