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())

			}

		}
	}

}
Beispiel #3
0
// readARP watches a handle for incoming ARP responses we might care about, and prints them.
//
// readARP loops until 'stop' is closed.
func readARP(handle *pcap.Handle, iface *net.Interface, stop chan struct{}) {
	src := gopacket.NewPacketSource(handle, layers.LayerTypeEthernet)
	in := src.Packets()
	for {
		var packet gopacket.Packet
		select {
		case <-stop:
			return
		case packet = <-in:
			arpLayer := packet.Layer(layers.LayerTypeARP)
			if arpLayer == nil {
				continue
			}
			arp := arpLayer.(*layers.ARP)
			if arp.Operation != layers.ARPReply || bytes.Equal([]byte(iface.HardwareAddr), arp.SourceHwAddress) {
				// This is a packet I sent.
				continue
			}
			// Note:  we might get some packets here that aren't responses to ones we've sent,
			// if for example someone else sends US an ARP request.  Doesn't much matter, though...
			// all information is good information :)
			log.Printf("IP %v is at %v", net.IP(arp.SourceProtAddress), net.HardwareAddr(arp.SourceHwAddress))
		}
	}
}
Beispiel #4
0
func TestPcapFileRead(t *testing.T) {
	for _, file := range []struct {
		filename       string
		num            int
		expectedLayers []gopacket.LayerType
	}{
		{"test_loopback.pcap",
			24,
			[]gopacket.LayerType{
				layers.LayerTypeLoopback,
				layers.LayerTypeIPv6,
				layers.LayerTypeTCP,
			},
		},
		{"test_ethernet.pcap",
			16,
			[]gopacket.LayerType{
				layers.LayerTypeEthernet,
				layers.LayerTypeIPv4,
				layers.LayerTypeTCP,
			},
		},
		{"test_dns.pcap",
			10,
			[]gopacket.LayerType{
				layers.LayerTypeEthernet,
				layers.LayerTypeIPv4,
				layers.LayerTypeUDP,
				layers.LayerTypeDNS,
			},
		},
	} {
		t.Logf("\n\n\n\nProcessing file %s\n\n\n\n", file.filename)

		packets := []gopacket.Packet{}
		if handle, err := OpenOffline(file.filename); err != nil {
			t.Fatal(err)
		} else {
			packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
			for packet := range packetSource.Packets() {
				packets = append(packets, packet)
			}
		}
		if len(packets) != file.num {
			t.Fatal("Incorrect number of packets, want", file.num, "got", len(packets))
		}
		for i, p := range packets {
			t.Log(p.Dump())
			for _, layertype := range file.expectedLayers {
				if p.Layer(layertype) == nil {
					t.Fatal("Packet", i, "has no layer type\n%s", layertype, p.Dump())
				}
			}
		}
	}
}
Beispiel #5
0
func Run(src gopacket.PacketDataSource) {
	if !flag.Parsed() {
		log.Fatalln("Run called without flags.Parse() being called")
	}
	var dec gopacket.Decoder
	var ok bool
	if dec, ok = gopacket.DecodersByLayerName[*decoder]; !ok {
		log.Fatalln("No decoder named", *decoder)
	}
	source := gopacket.NewPacketSource(src, dec)
	source.Lazy = *lazy
	source.NoCopy = true
	fmt.Fprintln(os.Stderr, "Starting to read packets")
	count := 0
	bytes := int64(0)
	start := time.Now()
	errors := 0
	truncated := 0
	layertypes := map[gopacket.LayerType]int{}
	for packet := range source.Packets() {
		count++
		bytes += int64(len(packet.Data()))
		if *dump {
			fmt.Println(packet.Dump())
		} else if *print {
			fmt.Println(packet)
		}
		if !*lazy || *print || *dump { // if we've already decoded all layers...
			for _, layer := range packet.Layers() {
				layertypes[layer.LayerType()]++
			}
			if packet.Metadata().Truncated {
				truncated++
			}
			if errLayer := packet.ErrorLayer(); errLayer != nil {
				errors++
				if *printErrors {
					fmt.Println("Error:", errLayer.Error())
					fmt.Println("--- Packet ---")
					fmt.Println(packet.Dump())
				}
			}
		}
		done := *maxcount > 0 && count >= *maxcount
		if count%*statsevery == 0 || done {
			fmt.Fprintf(os.Stderr, "Processed %v packets (%v bytes) in %v, %v errors and %v truncated packets\n", count, bytes, time.Since(start), errors, truncated)
			if len(layertypes) > 0 {
				fmt.Fprintf(os.Stderr, "Layer types seen: %+v\n", layertypes)
			}
		}
		if done {
			break
		}
	}
}
Beispiel #6
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))
		}
	}
}
Beispiel #7
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())
		}
	}
}
Beispiel #8
0
func (tap *Wiretap) capture(handle *pcap.Handle, channel chan gopacket.Packet) {
	defer handle.Close()

	src := gopacket.NewPacketSource(handle, handle.LinkType())
	src.DecodeOptions = gopacket.NoCopy

	for {
		packet, err := src.NextPacket()
		if err == io.EOF {
			return
		} else if err == nil {
			channel <- packet
		}
	}
}
Beispiel #9
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)
		}
	}
}
Beispiel #10
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()
		}
	}
}
Beispiel #11
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))
		}
	}
}
Beispiel #12
0
func main() {
	APList = make(map[string]AP)
	log.Println("Starting deauth-demo")
	//handle, err := pcap.OpenLive("em1", 1600, true, 0)
	handle, err := pcap.OpenOffline("/home/iniuser/Downloads/bssidcap.pcapng")
	if err != nil {
		log.Fatal("Error starting capture:", err)
	}
	err = handle.SetBPFFilter("(type mgt subtype beacon) or (type mgt subtype probe-req)")
	if err != nil {
		log.Fatal("Error setting bpf:", err)
	}
	source := gopacket.NewPacketSource(handle, handle.LinkType())
	for packet := range source.Packets() {
		if errPack := packet.ErrorLayer(); errPack != nil {
			log.Println("Packet could not be decoded:", errPack)
		}
		handlePacket(packet)
	}
	log.Println(APList)
}
Beispiel #13
0
func listen(iface net.Interface, port int) {
	snaplen := 65535
	handle, err := OpenLive(iface.Name, int32(snaplen), true, time.Second*1)

	if err != nil {
		log.Fatal(err)
	}

	err = handle.SetBPFFilter("tcp and port " + strconv.Itoa(port))

	log.Printf("Listening to HTTP traffic on port %d on interface %s", port, iface.Name)

	if err != nil {
		log.Fatal(err)
	}

	factory := httpStreamFactory{port: port}
	pool := tcpassembly.NewStreamPool(&factory)
	assembler := tcpassembly.NewAssembler(pool)

	packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
	packets := packetSource.Packets()
	ticker := time.Tick(time.Minute)
	for {
		select {
		case packet := <-packets:
			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))
		}
	}
}
//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
		}
	}
}
Beispiel #15
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))
		}
	}
}
func main() {
	if handle, err := pcap.OpenOffline("test.pcap"); err != nil {
		panic(err)
	} else {
		packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
		for packet := range packetSource.Packets() {
			//spew.Dump(packet.ApplicationLayer().Payload())
			payload := packet.ApplicationLayer().Payload()
			var p TLSHandshakeDecoder.TLSRecordLayer
			// decode record layer
			err = TLSHandshakeDecoder.DecodeRecord(&p, payload)
			if err != nil {
				panic(err)
			} else {
				// decode handshake
				//spew.Dump(p)
				var ph TLSHandshakeDecoder.TLSHandshake
				err = TLSHandshakeDecoder.TLSDecodeHandshake(&ph, p.Fragment)
				if err != nil {
					panic(err)
				} else {
					// decode client hello packet
					//spew.Dump(ph)
					var pch TLSHandshakeDecoder.TLSClientHello
					err = TLSHandshakeDecoder.TLSDecodeClientHello(&pch, ph.Body)
					if err != nil {
						panic(err)
					} else {
						//fmt.Printf("%#v\n", pch)
						spew.Dump(pch)
					}
				}
			}
			//return
		}
	}
}
Beispiel #17
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)

    }()

}
Beispiel #18
0
func main() {
	flag.Parse()
	filename := os.TempDir() + string(os.PathSeparator) + "gopacket_benchmark.pcap"
	if _, err := os.Stat(filename); err != nil {
		// This URL points to a publicly available packet data set from a DARPA
		// intrusion detection evaluation.  See
		// http://www.ll.mit.edu/mission/communications/cyber/CSTcorpora/ideval/data/1999/training/week1/index.html
		// for more details.
		fmt.Println("Local pcap file", filename, "doesn't exist, reading from", *url)
		if resp, err := http.Get(*url); err != nil {
			panic(err)
		} else if out, err := os.Create(filename); err != nil {
			panic(err)
		} else if gz, err := gzip.NewReader(resp.Body); err != nil {
			panic(err)
		} else if n, err := io.Copy(out, gz); err != nil {
			panic(err)
		} else if err := gz.Close(); err != nil {
			panic(err)
		} else if err := out.Close(); err != nil {
			panic(err)
		} else {
			fmt.Println("Successfully read", n, "bytes from url, unzipped to local storage")
		}
	}
	fmt.Println("Reading file once through to hopefully cache most of it")
	if f, err := os.Open(filename); err != nil {
		panic(err)
	} else if n, err := io.Copy(ioutil.Discard, f); err != nil {
		panic(err)
	} else if err := f.Close(); err != nil {
		panic(err)
	} else {
		fmt.Println("Read in file", filename, ", total of", n, "bytes")
	}
	if *cpuProfile != "" {
		if cpu, err := os.Create(*cpuProfile); err != nil {
			panic(err)
		} else if err := pprof.StartCPUProfile(cpu); err != nil {
			panic(err)
		} else {
			defer func() {
				pprof.StopCPUProfile()
				cpu.Close()
			}()
		}
	}
	var packetDataSource *BufferPacketSource
	var packetSource *gopacket.PacketSource
	fmt.Printf("Opening file %q for read\n", filename)
	if h, err := pcap.OpenOffline(filename); err != nil {
		panic(err)
	} else {
		fmt.Println("Reading all packets into memory with BufferPacketSource.")
		start := time.Now()
		packetDataSource = NewBufferPacketSource(h)
		duration := time.Since(start)
		fmt.Printf("Time to read packet data into memory from file: %v\n", duration)
		packetSource = gopacket.NewPacketSource(packetDataSource, h.LinkType())
		packetSource.DecodeOptions.Lazy = *decodeLazy
		packetSource.DecodeOptions.NoCopy = *decodeNoCopy
	}
	for i := 0; i < *repeat; i++ {
		packetDataSource.Reset()
		count, errors := 0, 0
		runtime.GC()
		fmt.Printf("Benchmarking decode %d/%d\n", i+1, *repeat)
		start := time.Now()
		for packet, err := packetSource.NextPacket(); err != io.EOF; packet, err = packetSource.NextPacket() {
			if err != nil {
				fmt.Println("Error reading in packet:", err)
			}
			count++
			var hasError bool
			if *printErrors && packet.ErrorLayer() != nil {
				fmt.Println("\n\n\nError decoding packet:", packet.ErrorLayer().Error())
				fmt.Println(hex.Dump(packet.Data()))
				fmt.Printf("%#v\n", packet.Data())
				errors++
				hasError = true
			}
			if *printLayers || hasError {
				fmt.Printf("\n=== PACKET %d ===\n", count)
				for _, l := range packet.Layers() {
					fmt.Printf("--- LAYER %v ---\n%#v\n\n", l.LayerType(), l)
				}
				fmt.Println()
			}
		}
		duration := time.Since(start)
		fmt.Printf("\tRead in %v packets in %v, %v per packet\n", count, duration, duration/time.Duration(count))
		if *printErrors {
			fmt.Printf("%v errors, successfully decoded %.02f%%\n", errors, float64(count-errors)*100.0/float64(count))
		}
	}
}
Beispiel #19
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
}
Beispiel #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()
}
Beispiel #21
0
func main() {
	flag.Parse()
	filename := os.TempDir() + string(os.PathSeparator) + "gopacket_benchmark.pcap"
	if _, err := os.Stat(filename); err != nil {
		// This URL points to a publicly available packet data set from a DARPA
		// intrusion detection evaluation.  See
		// http://www.ll.mit.edu/mission/communications/cyber/CSTcorpora/ideval/data/1999/training/week1/index.html
		// for more details.
		fmt.Println("Local pcap file", filename, "doesn't exist, reading from", *url)
		if resp, err := http.Get(*url); err != nil {
			panic(err)
		} else if out, err := os.Create(filename); err != nil {
			panic(err)
		} else if gz, err := gzip.NewReader(resp.Body); err != nil {
			panic(err)
		} else if n, err := io.Copy(out, gz); err != nil {
			panic(err)
		} else if err := gz.Close(); err != nil {
			panic(err)
		} else if err := out.Close(); err != nil {
			panic(err)
		} else {
			fmt.Println("Successfully read", n, "bytes from url, unzipped to local storage")
		}
	}
	fmt.Println("Reading file once through to hopefully cache most of it")
	if f, err := os.Open(filename); err != nil {
		panic(err)
	} else if n, err := io.Copy(ioutil.Discard, f); err != nil {
		panic(err)
	} else if err := f.Close(); err != nil {
		panic(err)
	} else {
		fmt.Println("Read in file", filename, ", total of", n, "bytes")
	}
	if *cpuProfile != "" {
		if cpu, err := os.Create(*cpuProfile); err != nil {
			panic(err)
		} else if err := pprof.StartCPUProfile(cpu); err != nil {
			panic(err)
		} else {
			defer func() {
				pprof.StopCPUProfile()
				cpu.Close()
			}()
		}
	}
	var packetDataSource *BufferPacketSource
	var packetSource *gopacket.PacketSource
	fmt.Printf("Opening file %q for read\n", filename)
	if h, err := pcap.OpenOffline(filename); err != nil {
		panic(err)
	} else {
		fmt.Println("Reading all packets into memory with BufferPacketSource.")
		start := time.Now()
		packetDataSource = NewBufferPacketSource(h)
		duration := time.Since(start)
		fmt.Printf("Time to read packet data into memory from file: %v\n", duration)
		packetSource = gopacket.NewPacketSource(packetDataSource, h.LinkType())
		packetSource.DecodeOptions.Lazy = *decodeLazy
		packetSource.DecodeOptions.NoCopy = *decodeNoCopy
	}
	fmt.Println()
	for i := 0; i < *repeat; i++ {
		packetDataSource.Reset()
		fmt.Printf("Benchmarking decode %d/%d\n", i+1, *repeat)
		benchmarkPacketDecode(packetSource)
	}
	fmt.Println()
	for i := 0; i < *repeat; i++ {
		packetDataSource.Reset()
		fmt.Printf("Benchmarking decoding layer parser %d/%d\n", i+1, *repeat)
		benchmarkLayerDecode(packetDataSource, false)
	}
	fmt.Println()
	for i := 0; i < *repeat; i++ {
		packetDataSource.Reset()
		fmt.Printf("Benchmarking decoding layer parser with assembly %d/%d\n", i+1, *repeat)
		benchmarkLayerDecode(packetDataSource, true)
	}
}