Example #1
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 #2
0
// startReceivingReplies createa a goroutine to read packets via a pcap sniffer
func (o *NFQueueTraceObserver) startReceivingReplies() {
	log.Print("startReceivingReplies\n")
	snaplen := 65536 // XXX make this a user specified option!
	filter := "icmp or tcp"

	handle, err := pcap.OpenLive(o.options.Iface, int32(snaplen), true, pcap.BlockForever)
	if err != nil {
		log.Fatal("error opening pcap handle: ", err)
	}
	if err := handle.SetBPFFilter(filter); err != nil {
		log.Fatal("error setting BPF filter: ", err)
	}

	o.startParsingReplies()

	go func() {
	Loop:
		for {
			select {
			case <-o.stopReceiveChan:
				break Loop
			default:
				data, _, err := handle.ReadPacketData()
				if err != nil {
					continue
				}
				o.receiveParseChan <- data
			}
		}
		close(o.receiveParseChan)
	}()
}
Example #3
0
func (s *PcapSniffer) Open(config *Config) error {
	// Capture settings
	const (
		// Max packet length
		snaplen int32 = 65536
		// Set the interface in promiscuous mode
		promisc bool = true
		// Timeout duration
		flushAfter string = "10s"
		//BPF filter when capturing packets
		filter string = "ip"
	)

	// Open the interface
	flushDuration, err := time.ParseDuration(flushAfter)
	if err != nil {
		return fmt.Errorf("Invalid flush duration: %s", flushAfter)
	}
	handle, err := pcap.OpenLive(*iface, snaplen, promisc, flushDuration/2)
	if err != nil {
		return fmt.Errorf("Error opening pcap handle: %s", err)
	}
	if err := handle.SetBPFFilter(filter); err != nil {
		return fmt.Errorf("Error setting BPF filter: %s", err)
	}
	s.handle = handle

	return nil
}
Example #4
0
// newScanner creates a new scanner for a given destination IP address, using
// router to determine how to route packets to that IP.
func newScanner(ip net.IP, router routing.Router) (*scanner, error) {
	s := &scanner{
		dst: ip,
		opts: gopacket.SerializeOptions{
			FixLengths:       true,
			ComputeChecksums: true,
		},
		buf: gopacket.NewSerializeBuffer(),
	}
	// Figure out the route to the IP.
	iface, gw, src, err := router.Route(ip)
	if err != nil {
		return nil, err
	}
	log.Printf("scanning ip %v with interface %v, gateway %v, src %v", ip, iface.Name, gw, src)
	s.gw, s.src, s.iface = gw, src, iface

	// Open the handle for reading/writing.
	// Note we could very easily add some BPF filtering here to greatly
	// decrease the number of packets we have to look at when getting back
	// scan results.
	handle, err := pcap.OpenLive(iface.Name, 65536, true, time.Millisecond)
	if err != nil {
		return nil, err
	}
	s.handle = handle
	return s, nil
}
func main() {
	var (
		device  = flag.String("device", "en0", "device to listen to")
		timeout = flag.Duration("timeout", pcap.BlockForever, "time intervals to parse captured packets")
	)
	flag.Parse()

	const (
		MTULen          = 1500
		promiscuousMode = true
	)

	handle, err := pcap.OpenLive(*device, MTULen, promiscuousMode, *timeout)
	// handle, err := pcap.OpenOffline("./dump_one.pcap")
	if err != nil {
		log.Fatalln(err)
	}

	packetSource := gopacket.NewPacketSource(handle, handle.LinkType())

	go countBytes(goingChan)

	go func() {
		for packet := range packetSource.Packets() {
			go handlePacket(packet, goingChan)
		}
	}()

	http.HandleFunc("/count", showClientMap)
	http.Handle("/", http.FileServer(http.Dir("./")))

	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatalln(err)
	}
}
func main() {
	fmt.Println("Hello World!")

	if handle, err := pcap.OpenLive("eno16777736", 1600, true, 0); err != nil {
		panic(err)
	} else if err := handle.SetBPFFilter("tcp and port 8005"); err != nil { // optional
		panic(err)
	} else {
		packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
		for packet := range packetSource.Packets() {

			// Get the TCP layer from this packet
			if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil {
				fmt.Println("This is a TCP packet!")
				// Get actual TCP data from this layer
				tcp, _ := tcpLayer.(*layers.TCP)
				fmt.Printf("From src port %d to dst port %d\n", tcp.SrcPort, tcp.DstPort)
				tcp.SrcPort = 5000
				fmt.Printf("New src src port is %d", tcp.SrcPort)
			}
			// Iterate over all layers, printing out each layer type
			for _, layer := range packet.Layers() {
				fmt.Println("PACKET LAYER:", layer.LayerType())

			}

		}
	}

}
Example #7
0
func main() {
	flag.Parse()
	var handle *pcap.Handle
	var err error
	if *fname != "" {
		if handle, err = pcap.OpenOffline(*fname); err != nil {
			log.Fatalln("PCAP OpenOffline error:", err)
		}
	} else {
		if handle, err = pcap.OpenLive(*iface, int32(*snaplen), true, time.Second); err != nil {
			log.Fatalln("PCAP OpenLive error:", err)
		}
		if *tstype != "" {
			if t, err := pcap.TimestampSourceFromString(*tstype); err != nil {
				log.Fatalf("Supported timestamp types: %v", handle.SupportedTimestamps())
			} else if err := handle.SetTimestampSource(t); err != nil {
				log.Fatalf("Supported timestamp types: %v", handle.SupportedTimestamps())
			}
		}
		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.Fatalln("BPF filter error:", err)
			}
		}
	}
	dumpcommand.Run(handle)
}
Example #8
0
func (tap *Wiretap) packets() chan gopacket.Packet {
	channel := make(chan gopacket.Packet, 100)
	filter := tap.Sources.Filter()

	n := 0
	for _, intf := range tap.Interfaces {
		handle, err := pcap.OpenLive(intf, tap.BufSize, tap.Sources.RequiresPromisc(), tap.Timeout)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Error: %s\n", err)
			continue
		}

		if err := handle.SetBPFFilter(filter); err != nil {
			fmt.Fprintf(os.Stderr, "Error: %s\n", err)
			continue
		}

		n++
		go tap.capture(handle, channel)
	}

	if n == 0 {
		panic("no devices could be wiretapped")
	}

	return channel
}
Example #9
0
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))
		}
	}
}
Example #10
0
func main() {
	if handle, err := pcap.OpenLive("eth0", 1600, true, 0); err != nil {
		panic(err)
	} else if err := handle.SetBPFFilter("tcp and port 80"); err != nil { // optional
		panic(err)
	} else {
		packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
		for packet := range packetSource.Packets() {
			fmt.Println(packet.String())
		}
	}
}
Example #11
0
// scan scans an individual interface's local network for machines using ARP requests/replies.
//
// scan loops forever, sending packets out regularly.  It returns an error if
// it's ever unable to write a packet.
func scan(iface *net.Interface) error {
	// We just look for IPv4 addresses, so try to find if the interface has one.
	var addr *net.IPNet
	if addrs, err := iface.Addrs(); err != nil {
		return err
	} else {
		for _, a := range addrs {
			if ipnet, ok := a.(*net.IPNet); ok {
				if ip4 := ipnet.IP.To4(); ip4 != nil {
					addr = &net.IPNet{
						IP:   ip4,
						Mask: ipnet.Mask[len(ipnet.Mask)-4:],
					}
					break
				}
			}
		}
	}
	// Sanity-check that the interface has a good address.
	if addr == nil {
		return fmt.Errorf("no good IP network found")
	} else if addr.IP[0] == 127 {
		return fmt.Errorf("skipping localhost")
	} else if addr.Mask[0] != 0xff || addr.Mask[1] != 0xff {
		return fmt.Errorf("mask means network is too large")
	}
	log.Printf("Using network range %v for interface %v", addr, iface.Name)

	// Open up a pcap handle for packet reads/writes.
	handle, err := pcap.OpenLive(iface.Name, 65536, true, pcap.BlockForever)
	if err != nil {
		return err
	}
	defer handle.Close()

	// Start up a goroutine to read in packet data.
	stop := make(chan struct{})
	go readARP(handle, iface, stop)
	defer close(stop)
	for {
		// Write our scan packets out to the handle.
		if err := writeARP(handle, iface, addr); err != nil {
			log.Printf("error writing packets on %v: %v", iface.Name, err)
			return err
		}
		// We don't know exactly how long it'll take for packets to be
		// sent back to us, but 10 seconds should be more than enough
		// time ;)
		time.Sleep(10 * time.Second)
	}
}
Example #12
0
func openLiveHandle() (handle *pcap.Handle) {
	var err error
	if handle, err = pcap.OpenLive(gwiface, MTU, true, 0); err != nil {
		panic(err)
	}
	log.Println("Pcap", gwiface, "opened")
	if gfilter != "" {
		log.Println("BPFFilter", gfilter)
		if err = handle.SetBPFFilter(gfilter); err != nil {
			panic(err)
		}
	}
	return
}
Example #13
0
func main() {
	// open device(s) for reading
	if handle, err := pcap.OpenLive(InterfaceName, 1600, true, pcap.BlockForever); err != nil {
		panic(err)
		// set filter
	} else if err := handle.SetBPFFilter(FilterExpression); err != nil {
		panic(err)
	} else {
		// start capture
		packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
		// handle packets
		for packet := range packetSource.Packets() {
			spew.Dump(packet)
		}
	}
}
Example #14
0
func main() {
	defer util.Run()()
	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)
	for {
		select {
		case packet := <-packets:
			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 minute.
			log.Println("---- FLUSHING ----")
			assembler.FlushOlderThan(time.Now().Add(-timeout))
			streamFactory.collectOldStreams()
		}
	}
}
Example #15
0
func main() {
	flag.Parse()
	log.Printf("starting capture on interface %q", *iface)
	// Set up pcap packet capture
	handle, err := pcap.OpenLive(*iface, int32(*snaplen), true, 0)
	if err != nil {
		panic(err)
	}
	if err := handle.SetBPFFilter(*filter); err != nil {
		panic(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:
			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.Assemble(packet.NetworkLayer().NetworkFlow(), tcp)

		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 #16
0
func main() {
	flag.Parse()
	var handle *pcap.Handle
	var err error
	if *fname != "" {
		if handle, err = pcap.OpenOffline(*fname); err != nil {
			log.Fatalln("PCAP OpenOffline error:", err)
		}
	} else {
		if handle, err = pcap.OpenLive(*iface, int32(*snaplen), true, time.Second); err != nil {
			log.Fatalln("PCAP OpenLive error:", err)
		}
		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.Fatalln("BPF filter error:", err)
			}
		}
	}
	dumpcommand.Run(handle)
}
Example #17
0
func main() {
	handle, err := pcap.OpenLive("lo", 1600, true, 0)

	if err != nil {
		panic(err)
	}

	if err := handle.SetBPFFilter("tcp port 8080"); err != nil {
		panic(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:
			log.Printf("%+v", jkjpacket.Dump())
			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))
		}
	}
}
//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 #19
0
// This function gets the interface and configuration parameters from the core process
// and starts handling packets that are captured with gopacket.pcap
func (g *GPCapture) CaptureInterface(snapLen int32, promiscMode bool, bpfFilterString string,
                                     threadTerminationChan chan string,
                                     iwg *sync.WaitGroup) {
    go func() {
        defer g.CaptureDefer(threadTerminationChan)

        var (
            err                       error
            packetSource              *gopacket.PacketSource
        )

        SysLog.Info(g.iface+": setting up capture")

        // loopback does not support in/out-bound filters, thus ignore it
        if g.iface == "lo" {
            SysLog.Err(g.iface+": interface not supported")
            iwg.Done()
            return
        }

        // open packet stream from an interface
        if g.pcapHandle, err = pcap.OpenLive(g.iface, snapLen, promiscMode, 250*time.Millisecond); err != nil {
            SysLog.Err(g.iface+": could not open capture: "+err.Error())
            iwg.Done()
            return
        }

        // set the BPF filter. This has to be done in order to ensure that the link
        // type is identified correctly
        if e := g.pcapHandle.SetBPFFilter(bpfFilterString); e != nil {
            SysLog.Err(g.iface+": error setting BPF filter: " + e.Error())
            iwg.Done()
            return
        }
        SysLog.Debug(g.iface+": bpf set")

        // return from function in case the link type is zero (which can happen if the
        // specified interface does not exist (anymore))
        if g.pcapHandle.LinkType() == layers.LinkTypeNull {
            SysLog.Err(g.iface+": link type is null")
            iwg.Done()
            return
        }

        SysLog.Debug(g.iface+": link type: "+g.pcapHandle.LinkType().String())

        // specify the pcap as the source from which the packets will be read
        packetSource = gopacket.NewPacketSource(g.pcapHandle, g.pcapHandle.LinkType())

        // set the decoding options to lazy decoding in order to ensure that the packet
        // layers are only decoded once they are needed. Additionally, this is imperative
        // when GRE-encapsulated packets are decoded because otherwise the layers cannot
        // be detected correctly. Additionally set the link type for this interface
        packetSource.DecodeOptions = gopacket.Lazy
        g.linkType                 = int(g.pcapHandle.LinkType())

        SysLog.Debug(g.iface+": set packet source")

        iwg.Done()

        // perform the actual packet capturing:
        g.ReadPackets(packetSource)

    }()

}
Example #20
0
func main() {
	flag.Parse()
	args := flag.Args()
	if len(args) != 2 {
		log.Printf("Usage: %s <ip> <port>\n", os.Args[0])
		os.Exit(-1)
	}

	// parse the destination host and port from the command line args
	dstip := net.ParseIP(args[0]).To4()
	dport_, err := strconv.ParseInt(args[1], 10, 16)
	if err != nil {
		log.Fatal(err)
	}
	dport := layers.TCPPort(dport_)
	sport := layers.TCPPort(5000)

	// get our local ip.
	srcip, err := localIP(dstip)
	if err != nil {
		log.Fatal(err)
	}

	devs, err := pcap.FindAllDevs()
	if err != nil {
		log.Fatal(err)
	}

	dev := ""
	for _, d := range devs {
		for _, a := range d.Addresses {
			if bytes.Equal(a.IP, srcip) {
				dev = d.Name
			}
		}
		// if d.Description == "Realtek PCIe GBE Family Controller" {
		//   fmt.Println(d.Name)
		//   dev = d.Name
		// }

		// fmt.Println(dev.Description)
	}

	if dev == "" {
		log.Fatal("Could not find the appropriate adapter device")
	}

	srcmac, err := localMac(dev)
	if err != nil {
		log.Fatal(err)
	}

	dstmac, err := remoteMac(dev, srcmac, srcip, dstip)
	if err != nil {
		log.Fatal(err)
	}

	eth := &layers.Ethernet{
		SrcMAC:       srcmac,
		DstMAC:       dstmac,
		EthernetType: layers.EthernetTypeIPv4,
	}

	// Our IPv4 header
	ip := &layers.IPv4{
		Version:    4,
		IHL:        5,
		TOS:        0,
		Length:     20, // FIX
		Id:         2,
		Flags:      layers.IPv4DontFragment,
		FragOffset: 0, //16384,
		TTL:        3, //64,
		Protocol:   layers.IPProtocolTCP,
		Checksum:   0,
		SrcIP:      srcip,
		DstIP:      dstip,
	}

	// Our TCP header
	tcp := &layers.TCP{
		SrcPort:  sport,
		DstPort:  dport,
		Seq:      0,
		Ack:      0,
		SYN:      true,
		Window:   64240,
		Checksum: 0,
		Urgent:   0,
	}
	tcp.DataOffset = 5 // uint8(unsafe.Sizeof(tcp))
	tcp.SetNetworkLayerForChecksum(ip)

	buf := gopacket.NewSerializeBuffer()
	err = gopacket.SerializeLayers(
		buf,
		gopacket.SerializeOptions{
			ComputeChecksums: true, // automatically compute checksums
			FixLengths:       true,
		},
		eth, ip, tcp,
	)
	if err != nil {
		log.Fatal(err)
	}

	handle, err := pcap.OpenLive(`rpcap://`+dev, 65535, true, time.Second*1)
	if err != nil {
		log.Fatal(err)
	}
	defer handle.Close()

	var wg sync.WaitGroup

	handle.SetBPFFilter(fmt.Sprintf("tcp and host %s and host %s and port %d and port %d", srcip.String(), dstip.String(), sport, dport))
	packetSource := gopacket.NewPacketSource(handle, handle.LinkType())

	wg.Add(1)
	go func() {
		stop := false

		go func() {
			<-time.After(time.Second * 2)
			stop = true
		}()

		for {
			if stop {
				break
			}

			packet, err := packetSource.NextPacket()
			if err == io.EOF {
				break
			} else if err != nil {
				//log.Println("Error:", err)
				continue
			}

			if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil {
				tcp, _ := tcpLayer.(*layers.TCP)
				if tcp.SrcPort == dport && tcp.DstPort == sport {
					if tcp.SYN && tcp.ACK {
						fmt.Printf("Port %d is OPEN\n", dport_)
					} else {
						fmt.Printf("Port %d is CLOSED\n", dport_)
					}
					break
				}
				//fmt.Printf("From src port %d to dst port %d\n", tcp.SrcPort, tcp.DstPort)
			}
		}

		wg.Done()
	}()

	err = handle.WritePacketData(buf.Bytes())
	if err != nil {
		log.Fatal(err)
	}

	wg.Wait()
}
Example #21
0
// Sends an ARP request packet to determine the MAC address of an IP
func remoteMac(dev string, srcmac net.HardwareAddr, srcip, dstip net.IP) (net.HardwareAddr, error) {
	var dstmac net.HardwareAddr

	eth := &layers.Ethernet{
		SrcMAC:       srcmac,
		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:         1, //arp request
		SourceHwAddress:   srcmac,
		SourceProtAddress: srcip,
		DstHwAddress:      net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
		DstProtAddress:    dstip,
	}

	buf := gopacket.NewSerializeBuffer()
	err := gopacket.SerializeLayers(
		buf,
		gopacket.SerializeOptions{
			ComputeChecksums: true, // automatically compute checksums
			FixLengths:       true,
		},
		eth, arp,
	)
	if err != nil {
		return dstmac, err
	}

	handle, err := pcap.OpenLive(`rpcap://`+dev, 65535, true, time.Second*1)
	if err != nil {
		return dstmac, err
	}
	defer handle.Close()

	var wg sync.WaitGroup

	handle.SetBPFFilter(fmt.Sprintf("arp and ether host %s", srcmac.String()))
	packetSource := gopacket.NewPacketSource(handle, handle.LinkType())

	macchan := make(chan net.HardwareAddr, 1)

	wg.Add(1)
	go func() {
		stop := false

		go func() {
			<-time.After(time.Second * 2)
			stop = true
		}()

		for {
			if stop {
				break
			}

			packet, err := packetSource.NextPacket()
			if err == io.EOF {
				break
			} else if err != nil {
				//log.Println("Error:", err)
				continue
			}

			if arpLayer := packet.Layer(layers.LayerTypeARP); arpLayer != nil {
				arp_, _ := arpLayer.(*layers.ARP)

				if bytes.Equal(arp_.SourceProtAddress, dstip) && arp_.Operation == 2 {
					macchan <- arp_.SourceHwAddress
					break
				}
			}
		}

		wg.Done()
	}()

	err = handle.WritePacketData(buf.Bytes())
	if err != nil {
		return dstmac, err
	}

	wg.Wait()

	dstmac = <-macchan
	return dstmac, nil
}
Example #22
0
func main() {
	flag.Parse()
	log.Printf("starting capture on interface %q", *iface)
	// Set up pcap packet capture
	handle, err := pcap.OpenLive(*iface, int32(*snaplen), true, time.Minute)
	if err != nil {
		log.Fatal("error opening pcap handle: ", 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)

	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(time.Minute)

loop:
	for {
		// 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(-time.Minute * 2))
			nextFlush = time.Now().Add(time.Minute)
		}

		// 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, _, err := handle.ZeroCopyReadPacketData()

		if err != nil {
			log.Printf("error getting packet: %v", err)
			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)
		}
		// 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.Assemble(netFlow, &tcp)
				} else {
					log.Println("could not find IPv4 or IPv6 layer, inoring")
				}
				continue loop
			}
		}
		log.Println("could not find TCP layer")
	}
}