diff options
Diffstat (limited to 'vendor/github.com/google/gopacket/examples/arpscan/arpscan.go')
-rw-r--r-- | vendor/github.com/google/gopacket/examples/arpscan/arpscan.go | 188 |
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, ð, &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 -} |