Golang DHCP 服务器和客户端抓包程序:使用 gopacket 库
package main
import ( "fmt" "log" "net" "time"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
)
func main() { if handle, err := pcap.OpenLive('eth0', 65536, true, 100*time.Millisecond); err != nil { log.Fatal(err) } else { defer handle.Close() if err := handle.SetBPFFilter('udp and (port 67 or port 68)'); err != nil { log.Fatal(err) } else { packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) for packet := range packetSource.Packets() { if dhcpLayer := packet.Layer(layers.LayerTypeDHCPv4); dhcpLayer != nil { dhcp, _ := dhcpLayer.(*layers.DHCPv4) if dhcp.MessageType == layers.DHCPMsgTypeDiscover { fmt.Println('Got DHCP Discover message from', dhcp.ClientHWAddr, 'with transaction ID', dhcp.TransactionID) // Create a new DHCP offer offer := &layers.DHCPv4{ MessageType: layers.DHCPMsgTypeOffer, TransactionID: dhcp.TransactionID, ClientHWAddr: dhcp.ClientHWAddr, YourClientIP: net.IPv4(192, 168, 199, 2), Options: []layers.DHCPOption{ layers.NewDHCPOption(layers.DHCPOptSubnetMask, net.IPv4(255, 255, 255, 0)), layers.NewDHCPOption(layers.DHCPOptRouter, net.IPv4(192, 168, 199, 1)), layers.NewDHCPOption(layers.DHCPOptDNS, net.IPv4(8, 8, 8, 8)), layers.NewDHCPOption(layers.DHCPOptDomainName, []byte('example.com')), layers.NewDHCPOption(layers.DHCPOptLeaseTime, []byte{0, 0, 4, 32}), // 4 hours }, } // Serialize the DHCP offer and send it back to the client if offerBytes, err := offer.SerializeTo(nil); err != nil { log.Println(err) } else { ethLayer := packet.Layer(layers.LayerTypeEthernet) eth, _ := ethLayer.(*layers.Ethernet) ipv4Layer := packet.Layer(layers.LayerTypeIPv4) ipv4, _ := ipv4Layer.(*layers.IPv4) udpLayer := packet.Layer(layers.LayerTypeUDP) udp, _ := udpLayer.(*layers.UDP) if udp.SrcPort == 67 { // Send the DHCP offer to the client eth.SrcMAC, eth.DstMAC = eth.DstMAC, eth.SrcMAC ipv4.SrcIP, ipv4.DstIP = ipv4.DstIP, ipv4.SrcIP udp.SrcPort, udp.DstPort = udp.DstPort, udp.SrcPort handle.WritePacketData(offerBytes) fmt.Println('Sent DHCP Offer message to', dhcp.ClientHWAddr) } else if udp.SrcPort == 68 { // Send the DHCP offer to the server eth.DstMAC = net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff} ipv4.SrcIP, ipv4.DstIP = ipv4.DstIP, net.IPv4(255, 255, 255, 255) udp.SrcPort, udp.DstPort = udp.DstPort, udp.SrcPort handle.WritePacketData(offerBytes) fmt.Println('Sent DHCP Offer message to server') } } } else if dhcp.MessageType == layers.DHCPMsgTypeRequest { fmt.Println('Got DHCP Request message from', dhcp.ClientHWAddr, 'with transaction ID', dhcp.TransactionID) // Create a new DHCP ACK ack := &layers.DHCPv4{ MessageType: layers.DHCPMsgTypeAck, TransactionID: dhcp.TransactionID, ClientHWAddr: dhcp.ClientHWAddr, YourClientIP: dhcp.RequestedIPAddress, Options: []layers.DHCPOption{ layers.NewDHCPOption(layers.DHCPOptSubnetMask, net.IPv4(255, 255, 255, 0)), layers.NewDHCPOption(layers.DHCPOptRouter, net.IPv4(192, 168, 199, 1)), layers.NewDHCPOption(layers.DHCPOptDNS, net.IPv4(8, 8, 8, 8)), layers.NewDHCPOption(layers.DHCPOptDomainName, []byte('example.com')), layers.NewDHCPOption(layers.DHCPOptLeaseTime, []byte{0, 0, 4, 32}), // 4 hours }, } // Serialize the DHCP ACK and send it back to the client if ackBytes, err := ack.SerializeTo(nil); err != nil { log.Println(err) } else { ethLayer := packet.Layer(layers.LayerTypeEthernet) eth, _ := ethLayer.(*layers.Ethernet) ipv4Layer := packet.Layer(layers.LayerTypeIPv4) ipv4, _ := ipv4Layer.(*layers.IPv4) udpLayer := packet.Layer(layers.LayerTypeUDP) udp, _ := udpLayer.(*layers.UDP) if udp.SrcPort == 67 { // Send the DHCP ACK to the client eth.SrcMAC, eth.DstMAC = eth.DstMAC, eth.SrcMAC ipv4.SrcIP, ipv4.DstIP = ipv4.DstIP, ipv4.SrcIP udp.SrcPort, udp.DstPort = udp.DstPort, udp.SrcPort handle.WritePacketData(ackBytes) fmt.Println('Sent DHCP ACK message to', dhcp.ClientHWAddr) } else if udp.SrcPort == 68 { // Send the DHCP ACK to the server eth.DstMAC = net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff} ipv4.SrcIP, ipv4.DstIP = ipv4.DstIP, net.IPv4(255, 255, 255, 255) udp.SrcPort, udp.DstPort = udp.DstPort, udp.SrcPort handle.WritePacketData(ackBytes) fmt.Println('Sent DHCP ACK message to server') } } } } } } }
原文地址: https://www.cveoy.top/t/topic/luZm 著作权归作者所有。请勿转载和采集!