aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/google/gopacket/examples/arpscan/arpscan.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/google/gopacket/examples/arpscan/arpscan.go')
-rw-r--r--vendor/github.com/google/gopacket/examples/arpscan/arpscan.go188
1 files changed, 0 insertions, 188 deletions
diff --git a/vendor/github.com/google/gopacket/examples/arpscan/arpscan.go b/vendor/github.com/google/gopacket/examples/arpscan/arpscan.go
deleted file mode 100644
index 1a0e33e..0000000
--- a/vendor/github.com/google/gopacket/examples/arpscan/arpscan.go
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright 2012 Google, Inc. All rights reserved.
-//
-// Use of this source code is governed by a BSD-style license
-// that can be found in the LICENSE file in the root of the source
-// tree.
-
-// arpscan implements ARP scanning of all interfaces' local networks using
-// gopacket and its subpackages. This example shows, among other things:
-// * Generating and sending packet data
-// * Reading in packet data and interpreting it
-// * Use of the 'pcap' subpackage for reading/writing
-package main
-
-import (
- "bytes"
- "encoding/binary"
- "errors"
- "log"
- "net"
- "sync"
- "time"
-
- "github.com/google/gopacket"
- "github.com/google/gopacket/layers"
- "github.com/google/gopacket/pcap"
-)
-
-func main() {
- // Get a list of all interfaces.
- ifaces, err := net.Interfaces()
- if err != nil {
- panic(err)
- }
-
- var wg sync.WaitGroup
- for _, iface := range ifaces {
- wg.Add(1)
- // Start up a scan on each interface.
- go func(iface net.Interface) {
- defer wg.Done()
- if err := scan(&iface); err != nil {
- log.Printf("interface %v: %v", iface.Name, err)
- }
- }(iface)
- }
- // Wait for all interfaces' scans to complete. They'll try to run
- // forever, but will stop on an error, so if we get past this Wait
- // it means all attempts to write have failed.
- wg.Wait()
-}
-
-// 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 errors.New("no good IP network found")
- } else if addr.IP[0] == 127 {
- return errors.New("skipping localhost")
- } else if addr.Mask[0] != 0xff || addr.Mask[1] != 0xff {
- return errors.New("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)
- }
-}
-
-// 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))
- }
- }
-}
-
-// 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
-}
-
-// ips is a simple and not very good method for getting all IPv4 addresses from a
-// net.IPNet. It returns all IPs it can over the channel it sends back, closing
-// the channel when done.
-func ips(n *net.IPNet) (out []net.IP) {
- num := binary.BigEndian.Uint32([]byte(n.IP))
- mask := binary.BigEndian.Uint32([]byte(n.Mask))
- num &= mask
- for mask < 0xffffffff {
- var buf [4]byte
- binary.BigEndian.PutUint32(buf[:], num)
- out = append(out, net.IP(buf[:]))
- mask += 1
- num += 1
- }
- return
-}