package main

import ( "fmt" "log" "net"

"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"

)

func main() { ifs, err := net.Interfaces(); err != nil { log.Fatal(err) }

var eth1 net.Interface
for _, i := range ifs {
	if i.Name == "eth1" {
		eth1 = i
		break
	}
}

handle, err := pcap.OpenLive(eth1.Name, 65536, true, pcap.BlockForever)
if err != nil {
	log.Fatal(err)
}
defer handle.Close()

filter := "udp and (port 67 or port 68)"
err = handle.SetBPFFilter(filter)
if err != nil {
	log.Fatal(err)
}

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

for packet := range packetSource.Packets() {
	udpLayer := packet.Layer(layers.LayerTypeUDP)
	if udpLayer != nil {
		udp, _ := udpLayer.(*layers.UDP)
		if udp.DstPort == 67 {
			ipv4Layer := packet.Layer(layers.LayerTypeIPv4)
			if ipv4Layer != nil {
				ipv4, _ := ipv4Layer.(*layers.IPv4)

				dstIP := net.ParseIP('192.168.199.1')
				dstMAC, err := getMAC(dstIP, eth1)
				if err != nil {
					log.Println(err)
					continue
				}

				eth := &layers.Ethernet{
					SrcMAC:       eth1.HardwareAddr,
					DstMAC:       dstMAC,
					EthernetType: layers.EthernetTypeIPv4,
				}

				ip := &layers.IPv4{
					Version:  4,
					TTL:      64,
					Protocol: layers.IPProtocolUDP,
					SrcIP:    ipv4.DstIP,
					DstIP:    dstIP,
				}

				udp.DstPort = 68

				err = handle.WritePacketData(gopacket.NewSerializeBuffer().SerializeLayers([]*layers.Layer{eth, ip, udp}))
				if err != nil {
					log.Println(err)
					continue
				}
			}
		}
	}
}

}

func getMAC(ip net.IP, iface net.Interface) (net.HardwareAddr, error) { conn, err := net.DialUDP('udp', nil, &net.UDPAddr{IP: ip, Port: 9}) if err != nil { return nil, err } defer conn.Close()

mac := make([]byte, 6)
copy(mac, iface.HardwareAddr)

magicPacket := make([]byte, 102)
for i := 0; i < 6; i++ {
	magicPacket[i] = 0xff
}
for i := 1; i <= 16; i++ {
	copy(magicPacket[i*6:(i+1)*6], mac)
}

_, err = conn.Write(magicPacket)
if err != nil {
	return nil, err
}

buf := make([]byte, 1024)
n, err := conn.Read(buf)
if err != nil {
	return nil, err
}

if n >= 6 {
	return buf[:6], nil
}

return nil, fmt.Errorf('failed to get MAC address for IP: %s', ip.String())

}


原文地址: https://www.cveoy.top/t/topic/luZY 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录