func main() { flag.Parse() var handle *pcap.Handle var err error 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) } packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) for packet := range packetSource.Packets() { if packet == nil { return } if udpLayer := packet.Layer(layers.LayerTypeUDP); udpLayer != nil { udp, _ := udpLayer.(*layers.UDP) fwdSIPPacket(udp.BaseLayer.Payload) } } }
//init re-initializes a snifer for uses func (s *Snifer) init() error { var handle *pcap.Handle var err error if s.conf.Offline { handle, err = pcap.OpenOffline(s.source) checkError(err, fmt.Sprintf("Create offline handle %s", s.source)) } else { handle, err = pcap.OpenLive(s.source, s.conf.MaxPacket, s.conf.Promod, s.conf.Timeout) checkError(err, fmt.Sprintf("Create Live handle %s", s.source)) if err == nil { err = handle.SetBPFFilter(s.conf.Filter) checkError(err, fmt.Sprintf("Setting BPFFilter %s: %s", s.source, s.conf.Filter)) } } if err != nil { checkError(err, fmt.Sprintf("Creating Snifer for %s", s.source)) return err } s.handle = handle log.Printf("Snifer: Handler created and ready!") return nil }
func getOpstream(cfg OpStreamSettings) (*packetHandlerContext, error) { if cfg.PacketBufSize < 1 { return nil, fmt.Errorf("invalid packet buffer size") } var pcapHandle *pcap.Handle var err error if len(cfg.PcapFile) > 0 { pcapHandle, err = pcap.OpenOffline(cfg.PcapFile) if err != nil { return nil, fmt.Errorf("error opening pcap file: %v", err) } } else if len(cfg.NetworkInterface) > 0 { pcapHandle, err = pcap.OpenLive(cfg.NetworkInterface, 32*1024*1024, false, pcap.BlockForever) if err != nil { return nil, fmt.Errorf("error listening to network interface: %v", err) } } else { return nil, fmt.Errorf("must specify either a pcap file or network interface to record from") } if len(cfg.Expression) > 0 { err = pcapHandle.SetBPFFilter(cfg.Expression) if err != nil { return nil, fmt.Errorf("error setting packet filter expression: %v", err) } } h := NewPacketHandler(pcapHandle) h.Verbose = userInfoLogger.isInVerbosity(DebugLow) toolDebugLogger.Logvf(Info, "Created packet buffer size %d", cfg.PacketBufSize) m := NewMongoOpStream(cfg.PacketBufSize) return &packetHandlerContext{h, m, pcapHandle}, nil }
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.Fatalln("Error: pcap file name is required!") // 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("\npacket:") // 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) log.Printf("\n.......................................................\n") log.Printf("packet:\n") log.Printf("packet.Metadata().Timestamp=%T=%v=%v:\n%#v\n", packet.Metadata().Timestamp, packet.Metadata().Timestamp, packet.Metadata().Timestamp.UTC(), packet.Metadata().Timestamp) 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 setupPcap(device *string, port *string, rediscommand_ch chan<- redis_protocol.RedisCommand) { var h *pcap.Handle var err error ifs, err_str := pcap.FindAllDevs() if len(ifs) == 0 { fmt.Printf("Warning: no devices found : %s\n", err_str) } h, err = pcap.OpenLive(*device, int32(65535), true, 1000) if h == nil { fmt.Printf("Openlive(%s) failed: %s\n", *device, err) return } defer h.Close() err = h.SetBPFFilter("dst port " + *port) if err != nil { fmt.Println("set filter failed") return } packetSource := gopacket.NewPacketSource(h, h.LinkType()) for pkt := range packetSource.Packets() { applicationLayer := pkt.ApplicationLayer() if applicationLayer == nil { continue } s := string(applicationLayer.Payload()) if s == "" { continue } rediscommand, err := redis_protocol.Parse(s) if err != nil { fmt.Println(err) continue } ipLayer := pkt.Layer(layers.LayerTypeIPv4) if ipLayer != nil { ip, _ := ipLayer.(*layers.IPv4) rediscommand.Ipaddr = []byte(ip.SrcIP.String()) } else { ipLayer := pkt.Layer(layers.LayerTypeIPv6) if ipLayer != nil { ip, _ := ipLayer.(*layers.IPv6) rediscommand.Ipaddr = []byte(ip.SrcIP.String()) } } rediscommand_ch <- *rediscommand } }
func tryCapture(iface net.Interface) error { if iface.Name[:2] == "lo" { return fmt.Errorf("skipping loopback") } var h *pcap.Handle var err error switch *mode { case "basic": h, err = pcap.OpenLive(iface.Name, 65536, false, time.Second*3) if err != nil { return fmt.Errorf("openlive: %v", err) } defer h.Close() case "filtered": h, err = pcap.OpenLive(iface.Name, 65536, false, time.Second*3) if err != nil { return fmt.Errorf("openlive: %v", err) } defer h.Close() if err := h.SetBPFFilter("port 80 or port 443"); err != nil { return fmt.Errorf("setbpf: %v", err) } case "timestamp": u, err := pcap.NewInactiveHandle(iface.Name) if err != nil { return err } defer u.CleanUp() if err = u.SetSnapLen(65536); err != nil { return err } else if err = u.SetPromisc(false); err != nil { return err } else if err = u.SetTimeout(time.Second * 3); err != nil { return err } sources := u.SupportedTimestamps() if len(sources) == 0 { return fmt.Errorf("no supported timestamp sources") } else if err := u.SetTimestampSource(sources[0]); err != nil { return fmt.Errorf("settimestampsource(%v): %v", sources[0], err) } else if h, err = u.Activate(); err != nil { return fmt.Errorf("could not activate: %v", err) } defer h.Close() default: panic("Invalid --mode: " + *mode) } go generatePackets() h.ReadPacketData() // Do one dummy read to clear any timeouts. data, ci, err := h.ReadPacketData() if err != nil { return fmt.Errorf("readpacketdata: %v", err) } log.Printf("Read packet, %v bytes, CI: %+v", len(data), ci) return nil }
func main() { defer util.Run()() var handle *pcap.Handle var err error signal.Notify(sigs, syscall.SIGHUP) go startWebServer() go sighandler() flag.Parse() go printDebugInfo() 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(true); 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) } } } for { process(handle) } }
// set packet capture filter, by ip and port func setDeviceFilter(handle *pcap.Handle, filterIP string, filterPort uint16) { var bpfFilter = "tcp" if filterPort != 0 { bpfFilter += " port " + strconv.Itoa(int(filterPort)) } if filterIP != "" { bpfFilter += " ip host " + filterIP } var err = handle.SetBPFFilter(bpfFilter) if err != nil { fmt.Fprintln(os.Stderr, "Set capture filter failed, ", err) } }
func main() { flag.Parse() filter := strings.Join(flag.Args(), " ") if device == NO_DEVICE && offlineFile == NO_OFFLINE_FILE { flag.Usage() os.Exit(1) } var ( handle *pcap.Handle err error ) if hasFile(offlineFile) { fmt.Printf("Reading packet from %s:\n", offlineFile) handle, err = pcap.OpenOffline(offlineFile) } else { fmt.Printf("Reading packet from %s:\n", device) handle, err = pcap.OpenLive( device, PACKET_SAMPLE_SIZE, true, pcap.BlockForever, ) } if err != nil { panic(err) } fmt.Printf("Applying filter: %s\n", filter) if err = handle.SetBPFFilter(filter); err != nil { panic(err) } for { packet, ci, err := handle.ReadPacketData() if err == io.EOF { break } if err != nil { panic(err) } go handlePacket(packet, ci) } }
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) } } } // https://github.com/google/gopacket/blob/master/dumpcommand/tcpdump.go dumpcommand.Run(handle) }
//setup a device or pcap file for capture, returns a handle func initHandle(config *pdnsConfig) *pcap.Handle { var handle *pcap.Handle var err error if config.device != "" && !config.pfring { handle, err = pcap.OpenLive(config.device, 65536, true, pcap.BlockForever) if err != nil { log.Debug(err) return nil } /* } else if dev != "" && pfring { handle, err = pfring.NewRing(dev, 65536, true, pfring.FlagPromisc) if err != nil { log.Debug(err) return nil } */ } else if config.pcapFile != "" { handle, err = pcap.OpenOffline(config.pcapFile) if err != nil { log.Debug(err) return nil } } else { log.Debug("You must specify either a capture device or a pcap file") return nil } err = handle.SetBPFFilter(config.bpf) if err != nil { log.Debug(err) return nil } /* if dev != "" && pfring { handle.Enable() } */ return handle }
func doReadPacket(handle *pcap.Handle) { var err error handle.SetBPFFilter(filter) if err != nil { log.Fatal(err) } for { data, ci, err := handle.ReadPacketData() switch { case err == io.EOF: return case err != nil: log.Println(err) default: packet := gopacket.NewPacket(data, layers.LayerTypeEthernet, gopacket.NoCopy) incomePacket := incomePacket{packet: packet, ci: &ci} switchPacket(incomePacket) } } }
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()) } } inactive.SetImmediateMode(true) 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) } } } packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) for packet := range packetSource.Packets() { if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil { if tcpLayer.(*layers.TCP).DstPort != 80 { continue } if tcpLayer.(*layers.TCP).SYN || tcpLayer.(*layers.TCP).RST { continue } data := string(tcpLayer.(*layers.TCP).LayerPayload()) if !strings.HasPrefix(data, "GET") { continue } fmt.Println("I got GET packet!") ethLayer := packet.Layer(layers.LayerTypeEthernet) eth := layers.Ethernet{ SrcMAC: ethLayer.(*layers.Ethernet).DstMAC, DstMAC: ethLayer.(*layers.Ethernet).SrcMAC, EthernetType: layers.EthernetTypeIPv4, } ipv4Layer := packet.Layer(layers.LayerTypeIPv4) ipv4 := layers.IPv4{ Version: ipv4Layer.(*layers.IPv4).Version, SrcIP: ipv4Layer.(*layers.IPv4).DstIP, DstIP: ipv4Layer.(*layers.IPv4).SrcIP, TTL: 77, Id: ipv4Layer.(*layers.IPv4).Id, Protocol: layers.IPProtocolTCP, } tcp := layers.TCP{ SrcPort: tcpLayer.(*layers.TCP).DstPort, DstPort: tcpLayer.(*layers.TCP).SrcPort, PSH: true, ACK: true, FIN: true, Seq: tcpLayer.(*layers.TCP).Ack, Ack: tcpLayer.(*layers.TCP).Seq + uint32(len(data)), Window: 0, } tcp.SetNetworkLayerForChecksum(&ipv4) data = `HTTP/1.1 200 OK Server: nginx Date: Tue, 26 Jan 2016 13:09:19 GMT Content-Type: text/plain;charset=UTF-8 Connection: keep-alive Vary: Accept-Encoding Cache-Control: no-store Pragrma: no-cache Expires: Thu, 01 Jan 1970 00:00:00 GMT Cache-Control: no-cache Content-Length: 7 Stupid!` // Set up buffer and options for serialization. buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{ FixLengths: true, ComputeChecksums: true, } if err := gopacket.SerializeLayers(buf, opts, ð, &ipv4, &tcp, gopacket.Payload([]byte(data))); err != nil { fmt.Println(err) } if err := handle.WritePacketData(buf.Bytes()); err != nil { fmt.Println(err) } fmt.Println("I sent Response-hijack packet!") } } // dumpcommand.Run(handle) }
func main() { defer util.Run()() var handle *pcap.Handle var err error flushDuration, err := time.ParseDuration(*flushAfter) if err != nil { log.Fatal("invalid flush duration: ", *flushAfter) } // log.Printf("starting capture on interface %q", *iface) // // Set up pcap packet capture // handle, err := pcap.OpenLive(*iface, int32(*snaplen), true, flushDuration/2) // if err != nil { // log.Fatal("error opening pcap handle: ", err) // } // Set up pcap packet capture if *fname != "" { log.Printf("Reading from pcap dump %q", *fname) handle, err = pcap.OpenOffline(*fname) } else { log.Fatalln("Error: pcap file name is required!") // 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("error setting BPF filter: ", err) } // Set up assembly streamFactory := &statsStreamFactory{} streamPool := tcpassembly.NewStreamPool(streamFactory) assembler := tcpassembly.NewAssembler(streamPool) assembler.MaxBufferedPagesPerConnection = *bufferedPerConnection assembler.MaxBufferedPagesTotal = *bufferedTotal log.Println("reading in packets") // We use a DecodingLayerParser here instead of a simpler PacketSource. // This approach should be measurably faster, but is also more rigid. // PacketSource will handle any known type of packet safely and easily, // but DecodingLayerParser will only handle those packet types we // specifically pass in. This trade-off can be quite useful, though, in // high-throughput situations. var eth layers.Ethernet var dot1q layers.Dot1Q var ip4 layers.IPv4 var ip6 layers.IPv6 var ip6extensions layers.IPv6ExtensionSkipper var tcp layers.TCP var payload gopacket.Payload parser := gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, ð, &dot1q, &ip4, &ip6, &ip6extensions, &tcp, &payload) decoded := make([]gopacket.LayerType, 0, 4) nextFlush := time.Now().Add(flushDuration / 2) var byteCount int64 start := time.Now() loop: for ; *packetCount != 0; *packetCount-- { // Check to see if we should flush the streams we have // that haven't seen any new data in a while. Note we set a // timeout on our PCAP handle, so this should happen even if we // never see packet data. if time.Now().After(nextFlush) { stats, _ := handle.Stats() log.Printf("flushing all streams that haven't seen packets in the last 2 minutes, pcap stats: %+v", stats) assembler.FlushOlderThan(time.Now().Add(flushDuration)) nextFlush = time.Now().Add(flushDuration / 2) } // To speed things up, we're also using the ZeroCopy method for // reading packet data. This method is faster than the normal // ReadPacketData, but the returned bytes in 'data' are // invalidated by any subsequent ZeroCopyReadPacketData call. // Note that tcpassembly is entirely compatible with this packet // reading method. This is another trade-off which might be // appropriate for high-throughput sniffing: it avoids a packet // copy, but its cost is much more careful handling of the // resulting byte slice. data, ci, err := handle.ZeroCopyReadPacketData() if err != nil { log.Printf("error getting packet: %v", err) break loop // continue } err = parser.DecodeLayers(data, &decoded) if err != nil { log.Printf("error decoding packet: %v", err) continue } if *logAllPackets { log.Printf("decoded the following layers: %v", decoded) } byteCount += int64(len(data)) // Find either the IPv4 or IPv6 address to use as our network // layer. foundNetLayer := false var netFlow gopacket.Flow for _, typ := range decoded { switch typ { case layers.LayerTypeIPv4: netFlow = ip4.NetworkFlow() foundNetLayer = true case layers.LayerTypeIPv6: netFlow = ip6.NetworkFlow() foundNetLayer = true case layers.LayerTypeTCP: if foundNetLayer { assembler.AssembleWithTimestamp(netFlow, &tcp, ci.Timestamp) } else { log.Println("could not find IPv4 or IPv6 layer, inoring") } continue loop } } log.Println("could not find TCP layer") } assembler.FlushAll() log.Printf("processed %d bytes in %v", byteCount, time.Since(start)) }
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.Fatalln("Error: pcap file name is required!") // log.Printf("Starting capture on interface %q", *iface) // handle, err = pcap.OpenLive(*iface, int32(*snaplen), true, pcap.BlockForever) } // log.Printf("starting capture on interface %q", *iface) // // Set up pcap packet capture // handle, err := pcap.OpenLive(*iface, int32(*snaplen), true, pcap.BlockForever) if err != nil { panic(err) } if err := handle.SetBPFFilter(*filter); err != nil { panic(err) } // Set up assembly streamFactory := &myFactory{bidiMap: make(map[key]*bidi)} 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(timeout / 4) ReadingPackets: for { select { case packet := <-packets: if *logAllPackets { log.Println(packet) } if packet == nil { log.Println("Unusable packet: if packet == nil") break ReadingPackets } if packet.NetworkLayer() == nil { log.Println("Unusable packet: if packet.NetworkLayer() == nil") break ReadingPackets } if packet.TransportLayer() == nil { log.Println("Unusable packet: if packet.TransportLayer() == nil") break ReadingPackets } if packet.TransportLayer().LayerType() != layers.LayerTypeTCP { log.Println("Unusable packet: if packet.TransportLayer().LayerType() != layers.LayerTypeTCP") break ReadingPackets } 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 minute. log.Println("---- FLUSHING ----") assembler.FlushOlderThan(time.Now().Add(-timeout)) streamFactory.collectOldStreams() } } }
func main() { var handle *pcap.Handle var err error flag.Parse() if *fname != "" { log.Printf("Reading from pcap file %q", *fname) handle, err = pcap.OpenOffline(*fname) } else { log.Printf("Starting capture on interface %q", *iface) handle, err = pcap.OpenLive(*iface, int32(*snaplen), false, pcap.BlockForever) } if err != nil { log.Fatal(err) } if *filter == "" { // from kcs_const.js *filter = "tcp port 80 and host" *filter += " (125.6.184.15 or 125.6.184.16 or 125.6.187.205 or" *filter += " 125.6.187.229 or 125.6.187.253 or 125.6.188.25 or" *filter += " 125.6.189.7 or 125.6.189.39 or 125.6.189.71 or" *filter += " 125.6.189.103 or 125.6.189.135 or 125.6.189.167 or" *filter += " 125.6.189.215 or 125.6.189.247 or 203.104.209.7 or" *filter += " 203.104.209.23 or 203.104.209.39 or 203.104.209.55 or" *filter += " 203.104.209.71 or 203.104.209.102 or 203.104.248.135)" } if err := handle.SetBPFFilter(*filter); err != nil { log.Fatal(err) } // Set up assembly streamFactory := &httpStreamFactory{} streamPool := tcpassembly.NewStreamPool(streamFactory) assembler := tcpassembly.NewAssembler(streamPool) // Set up paser goroutine cpus := runtime.NumCPU() runtime.GOMAXPROCS(cpus) wait := new(sync.WaitGroup) go parse(wait) // 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 packet.NetworkLayer() == nil || packet.TransportLayer() == nil { continue } if packet.TransportLayer().LayerType() != layers.LayerTypeTCP { 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)) } } parserCh <- Res{port: 0} wait.Wait() }
func getOpstream(cfg OpStreamSettings) (*packetHandlerContext, error) { if cfg.PacketBufSize < 1 { return nil, fmt.Errorf("invalid packet buffer size") } var pcapHandle *pcap.Handle var err error if len(cfg.PcapFile) > 0 { pcapHandle, err = pcap.OpenOffline(cfg.PcapFile) if err != nil { return nil, fmt.Errorf("error opening pcap file: %v", err) } } else if len(cfg.NetworkInterface) > 0 { inactive, err := pcap.NewInactiveHandle(cfg.NetworkInterface) if err != nil { return nil, fmt.Errorf("error creating a pcap handle: %v", err) } // This is safe; calling `Activate()` steals the underlying ptr. defer inactive.CleanUp() err = inactive.SetSnapLen(64 * 1024) if err != nil { return nil, fmt.Errorf("error setting snaplen on pcap handle: %v", err) } err = inactive.SetPromisc(false) if err != nil { return nil, fmt.Errorf("error setting promisc on pcap handle: %v", err) } err = inactive.SetTimeout(pcap.BlockForever) if err != nil { return nil, fmt.Errorf("error setting timeout on pcap handle: %v", err) } // CaptureBufSize is in KiB to match units on `tcpdump -B`. err = inactive.SetBufferSize(cfg.CaptureBufSize * 1024) if err != nil { return nil, fmt.Errorf("error setting buffer size on pcap handle: %v", err) } pcapHandle, err = inactive.Activate() if err != nil { return nil, fmt.Errorf("error listening to network interface: %v", err) } } else { return nil, fmt.Errorf("must specify either a pcap file or network interface to record from") } if len(cfg.Expression) > 0 { err = pcapHandle.SetBPFFilter(cfg.Expression) if err != nil { return nil, fmt.Errorf("error setting packet filter expression: %v", err) } } h := NewPacketHandler(pcapHandle) h.Verbose = userInfoLogger.isInVerbosity(DebugLow) toolDebugLogger.Logvf(Info, "Created packet buffer size %d", cfg.PacketBufSize) m := NewMongoOpStream(cfg.PacketBufSize) return &packetHandlerContext{h, m, pcapHandle}, nil }