package utils import ( "log" "net" "unicode/utf8" "github.com/google/gopacket" "github.com/google/gopacket/layers" "github.com/mdlayher/packet" ) type SocketCall struct { conn *packet.Conn Iface *net.Interface } func splitData(message string) []string { data := []string{} var i, j int for i, j = 0, 1458; j < len(message); i, j = j, j+1458 { for !utf8.RuneStart(message[j]) { j-- } data = append(data, message[i:j]) } data = append(data, message[i:]) return data } func (c* SocketCall)SendData(message string) { splitMessage := splitData(message) for i := 0; i < len(splitMessage); i++ { c.init(splitMessage[i]) } return } func (c* SocketCall)init(data string) { iface, _ := net.InterfaceByName("virbr0") conn, err := packet.Listen(iface, packet.Raw, int(layers.EthernetTypeIPv4), nil) payload := []byte(data) if len(payload) > 1500 { log.Printf("Larger than 1500 -- %d", len(payload)) } if err != nil { log.Panic(err) } c.Iface = iface c.conn = conn eth := layers.Ethernet{ EthernetType: layers.EthernetTypeIPv4, SrcMAC: c.Iface.HardwareAddr, DstMAC: layers.EthernetBroadcast, } ip := layers.IPv4{ Version: 4, TTL: 64, SrcIP: []byte{0, 0, 0, 0}, DstIP: []byte{255, 255, 255, 255}, Protocol: layers.IPProtocolUDP, } udp := layers.UDP{ SrcPort: 6868, DstPort: 6767, } buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{ ComputeChecksums: true, FixLengths: true, } udp.SetNetworkLayerForChecksum(&ip) err = gopacket.SerializeLayers(buf, opts, ð, &ip, &udp, gopacket.Payload(payload)) if err != nil { log.Panic(err) } _, err = c.conn.WriteTo(buf.Bytes(), &packet.Addr{HardwareAddr: eth.DstMAC}) if err != nil { log.Panic(err) } return }