package utils import ( "encoding/binary" "fmt" "log" "net" "unicode/utf8" "github.com/google/gopacket" "github.com/google/gopacket/layers" "github.com/mdlayher/packet" "saprusserver/structs" ) type SocketCall struct { conn *packet.Conn Iface *net.Interface } func splitData(message string) []string { data := []string{} maxPacketLength := 8 //maxPacketLength := 1458 var i, j int for i, j = 0, maxPacketLength; j < len(message); i, j = j, j+maxPacketLength { for !utf8.RuneStart(message[j]) { j-- } data = append(data, message[i:j]) } data = append(data, message[i:]) return data } func (c* SocketCall) SendPackage(buf gopacket.SerializeBuffer) error { _, err := c.conn.WriteTo(buf.Bytes(), &packet.Addr{HardwareAddr: layers.EthernetBroadcast}) return err } func (c* SocketCall)SendData(message string) { iface, _ := net.InterfaceByName("virbr0") c.Iface = iface conn, _ := packet.Listen(iface, packet.Raw, int(layers.EthernetTypeIPv4), nil) c.conn = conn splitMessage := splitData(message) for i := 0; i < len(splitMessage); i++ { c.SendPackage(c.FileTransferPacket(splitMessage[i])) } return } func (c* SocketCall) saprusPayloadLength(pkt []byte) [2]byte{ payloadLength := make([]byte, 2) var length [2]byte binary.BigEndian.PutUint16(payloadLength, uint16(len(pkt))) length[0] = payloadLength[0] length[1] = payloadLength[1] return length } func (c* SocketCall)init(data string) { iface, _ := net.InterfaceByName("virbr0") conn, err := packet.Listen(iface, packet.Raw, int(layers.EthernetTypeIPv4), nil) 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, } // FUCK THIS saprusPayloadLength := make([]byte, 2) binary.BigEndian.PutUint16(saprusPayloadLength, uint16(len(data))) var saprusPayloadLengthTwo [2]byte saprusPayloadLengthTwo[0] = saprusPayloadLength[0] saprusPayloadLengthTwo[1] = saprusPayloadLength[1] saprus := structs.SaprusHeaderFrame{ PacketType: [2]byte{0, 10}, Length: saprusPayloadLengthTwo, Payload: []byte(data), } buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{ ComputeChecksums: true, FixLengths: true, } udp.SetNetworkLayerForChecksum(&ip) err = gopacket.SerializeLayers(buf, opts, ð, &ip, &udp, gopacket.Payload(saprus.Bytes())) if err != nil { log.Panic(err) } _, err = c.conn.WriteTo(buf.Bytes(), &packet.Addr{HardwareAddr: eth.DstMAC}) if err != nil { log.Panic(err) } return }