Пример #1
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
}
Пример #2
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, pcap.BlockForever)
	if err != nil {
		return nil, err
	}
	s.handle = handle
	return s, nil
}
Пример #3
0
func TestInformationElement(t *testing.T) {
	bin := []byte{
		0, 0,
		0, 2, 1, 3,
		221, 5, 1, 2, 3, 4, 5,
	}
	pkt := gopacket.NewPacket(bin, LayerTypeDot11InformationElement, gopacket.NoCopy)

	buf := gopacket.NewSerializeBuffer()
	var sLayers []gopacket.SerializableLayer
	for _, l := range pkt.Layers() {
		sLayers = append(sLayers, l.(*Dot11InformationElement))
	}
	if err := gopacket.SerializeLayers(buf, gopacket.SerializeOptions{}, sLayers...); err != nil {
		t.Error(err.Error())
	}
	if !bytes.Equal(bin, buf.Bytes()) {
		t.Error("build failed")
	}
}
Пример #4
0
func (s *Server) ListenAndServeUDPv4() {
	ipAddr := &net.IPAddr{IP: net.IPv4zero}
	conn, err := net.ListenIP("ip4:udp", ipAddr)
	if err != nil {
		l.Info(err.Error())
		return
	}
	defer conn.Close()
	if err = bindToDevice(conn, "tap"+s.name); err != nil {
		l.Info(err.Error())
		return
	}

	s.Lock()
	s.ipv4conn, err = ipv4.NewRawConn(conn)
	s.Unlock()
	if err != nil {
		l.Info(err.Error())
		return
	}

	if err = s.ipv4conn.SetControlMessage(ipv4.FlagDst, true); err != nil {
		l.Warning(err.Error())
		return
	}

	buffer := make([]byte, 1500)

	var gw net.IP
	for _, addr := range s.metadata.Network.IP {
		if addr.Family == "ipv4" && addr.Host == "true" && addr.Gateway == "true" {
			gw = net.ParseIP(addr.Address)
		}
	}
	iface, err := net.InterfaceByName("tap" + s.name)
	if err != nil {
		l.Info(fmt.Sprintf("failed to get iface: %s", err.Error()))
		return
	}

	for {
		select {
		case <-s.done:
			return
		default:
			s.ipv4conn.SetReadDeadline(time.Now().Add(time.Second))
			hdr, _, _, err := s.ipv4conn.ReadFrom(buffer)
			if err != nil {
				switch v := err.(type) {
				case *net.OpError:
					if v.Timeout() {
						continue
					}
				case *net.AddrError:
					if v.Timeout() {
						continue
					}
				case *net.UnknownNetworkError:
					if v.Timeout() {
						continue
					}
				default:
					l.Warning(err.Error())
					return
				}
			}
			var ip4 layers.IPv4
			var udp layers.UDP
			var dhcp4req layers.DHCPv4
			parser := gopacket.NewDecodingLayerParser(layers.LayerTypeIPv4, &ip4, &udp, &dhcp4req)
			decoded := []gopacket.LayerType{}
			err = parser.DecodeLayers(buffer, &decoded)
			for _, layerType := range decoded {
				switch layerType {
				case layers.LayerTypeDHCPv4:
					if dhcp4req.Operation == layers.DHCP_MSG_REQ {
						dhcp4res, err := s.ServeUDPv4(&dhcp4req)
						if err != nil {
							l.Warning(err.Error())
							continue
						}
						if dhcp4res == nil {
							// ignore empty dhcp packets
							continue
						}

						buf := gopacket.NewSerializeBuffer()
						opts := gopacket.SerializeOptions{true, true}
						gopacket.SerializeLayers(buf, opts,
							&layers.UDP{SrcPort: 67, DstPort: 68},
							dhcp4res)

						wcm := ipv4.ControlMessage{TTL: 255}
						wcm.Dst = net.IPv4bcast.To4()
						wcm.Src = gw.To4()
						wcm.IfIndex = iface.Index
						err = s.ipv4conn.WriteTo(&ipv4.Header{Len: 20, TOS: hdr.TOS, TotalLen: 20 + int(len(buf.Bytes())), FragOff: 0, TTL: 255, Protocol: int(layers.IPProtocolUDP), Src: gw.To4(), Dst: net.IPv4bcast.To4()}, buf.Bytes(), &wcm)
						if err != nil {
							l.Warning(err.Error())
							continue
						}
					} else {
						continue
					}
				}
			}
		}
	}
}