Example #1
0
func writePacket(handle *pcap.Handle, buf []byte) error {
	if err := handle.WritePacketData(buf); err != nil {
		log.Printf("Failed to send packet: %s\n", err)
		return err
	}
	return nil
}
Example #2
0
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
}
Example #3
0
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)
		}
	}
}
Example #4
0
File: pcap.go Project: brb/weave
func (p *Pcap) sniff(readHandle *pcap.Handle, consumer BridgeConsumer) {
	dec := NewEthernetDecoder()

	for {
		pkt, _, err := readHandle.ZeroCopyReadPacketData()
		if err == pcap.NextErrorTimeoutExpired {
			continue
		}

		checkFatal(err)
		dec.DecodeLayers(pkt)
		if len(dec.decoded) == 0 {
			continue
		}

		if fop := consumer(dec.PacketKey()); !fop.Discards() {
			// We are handing over the frame to
			// forwarders, so we need to make a copy of it
			// in order to prevent the next capture from
			// overwriting the data
			pktLen := len(pkt)
			pktCopy := make([]byte, pktLen, pktLen)
			copy(pktCopy, pkt)

			fop.Process(pktCopy, dec, false)
		}
	}
}
Example #5
0
// writeARP writes an ARP request for each address on our local network to the
// pcap handle.
func writeARP(handle *pcap.Handle, iface *net.Interface, addr *net.IPNet) error {
	// Set up all the layers' fields we can.
	eth := layers.Ethernet{
		SrcMAC:       iface.HardwareAddr,
		DstMAC:       net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
		EthernetType: layers.EthernetTypeARP,
	}
	arp := layers.ARP{
		AddrType:          layers.LinkTypeEthernet,
		Protocol:          layers.EthernetTypeIPv4,
		HwAddressSize:     6,
		ProtAddressSize:   4,
		Operation:         layers.ARPRequest,
		SourceHwAddress:   []byte(iface.HardwareAddr),
		SourceProtAddress: []byte(addr.IP),
		DstHwAddress:      []byte{0, 0, 0, 0, 0, 0},
	}
	// Set up buffer and options for serialization.
	buf := gopacket.NewSerializeBuffer()
	opts := gopacket.SerializeOptions{
		FixLengths:       true,
		ComputeChecksums: true,
	}
	// Send one packet for every address.
	for _, ip := range ips(addr) {
		arp.DstProtAddress = []byte(ip)
		gopacket.SerializeLayers(buf, opts, &eth, &arp)
		if err := handle.WritePacketData(buf.Bytes()); err != nil {
			return err
		}
	}
	return nil
}
Example #6
0
//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 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))
		}
	}
}
Example #8
0
// 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 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)
	}
}
Example #10
0
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
}
Example #11
0
// 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)
	}
}
Example #12
0
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)
			}
		}
	}
}
Example #13
0
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)
	}
}
Example #14
0
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)
}
Example #15
0
func sendPacket(handle *pcap.Handle, sMac, dMac net.HardwareAddr, sIp, dIp net.IP, sPort, dPort layers.TCPPort, IpId uint16, IpTtl uint8, TcpSeq, ack uint32, WindowsSize uint16, data []byte) error {
	eth := layers.Ethernet{
		SrcMAC:       sMac,
		DstMAC:       dMac,
		EthernetType: layers.EthernetTypeIPv4,
	}
	ip4 := layers.IPv4{
		SrcIP:    sIp,
		DstIP:    dIp,
		Id:       IpId,
		Flags:    layers.IPv4DontFragment,
		Version:  4,
		TTL:      IpTtl,
		Protocol: layers.IPProtocolTCP,
	}
	tcp := layers.TCP{
		SrcPort: sPort,
		DstPort: dPort,
		Seq:     TcpSeq,
		ACK:     true,
		Ack:     ack,
		Window:  WindowsSize,
		PSH:     true, // 立刻处理
	}

	if len(data) == 0 {
		tcp.RST = true
	}

	tcp.SetNetworkLayerForChecksum(&ip4)

	buf := gopacket.NewSerializeBuffer()
	opts := gopacket.SerializeOptions{
		FixLengths:       true,
		ComputeChecksums: true,
	}

	payload := gopacket.Payload(data)

	if err := gopacket.SerializeLayers(buf, opts, &eth, &ip4, &tcp, payload); err != nil {
		return err
	}

	return handle.WritePacketData(buf.Bytes())
}
Example #16
0
//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
}
Example #17
0
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
	}
}
Example #18
0
File: pcap.go Project: adoyee/probe
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)
		}
	}

}
Example #19
0
//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
		}
	}
}
Example #20
0
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()
		}
	}
}
Example #22
0
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()
}
Example #23
0
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
}
Example #24
0
//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,
		&ethLayer,
		&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

	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,
		&eth, &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))
}
Example #26
0
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
}
Example #27
0
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, &eth, &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)
}