diff --git a/client/golang/client.go b/client/golang/client.go index ae08b1f..57be36f 100644 --- a/client/golang/client.go +++ b/client/golang/client.go @@ -3,15 +3,16 @@ package main import ( //"encoding/base64" "encoding/binary" - "errors" "fmt" - "net" + //"net" //"strings" "time" "github.com/google/gopacket" "github.com/google/gopacket/pcap" + + "client/utils" ) type SaprusHeaderPacket struct { @@ -75,40 +76,8 @@ func listenDiscoverResponse(addrChan chan string, readyFlag chan int) { return } -func toMaxHost(n *net.IPNet) (net.IP, error) { - if n.IP.To4() == nil { - return net.IP{}, errors.New("IP address is not IPv4") - } - - ip := make(net.IP, len(n.IP.To4())) - binary.BigEndian.PutUint32(ip, - binary.BigEndian.Uint32(n.IP.To4())|^binary.BigEndian.Uint32(net.IP(n.Mask).To4())) - - return ip, nil -} - -func bcastAddresses() []string { - var addrs []string = nil - interfaceInfo, _ := net.Interfaces() - for i := 0; i < len(interfaceInfo); i++ { - addr, err := interfaceInfo[i].Addrs() - errCheck(err) - for j := 0; j < len(addr); j++ { - _, ipNet, _ := net.ParseCIDR(addr[j].String()) - bcast, err := toMaxHost(ipNet) - - if err != nil { - } else { - addrs = append(addrs, bcast.String()) - } - } - } - - return addrs -} - func main() { - sendAddrs := bcastAddresses() + sendAddrs := []string{"255.255.255.255"} addrChan := make(chan string) readyFlag := make(chan int) @@ -119,15 +88,9 @@ func main() { <- readyFlag for i := 0; i < len(sendAddrs); i++ { - remoteAddr := sendAddrs[i] + ":8888" - remote, err := net.ResolveUDPAddr("udp4", remoteAddr) - errCheck(err) - conn, err := net.DialUDP("udp4", nil, remote) - errCheck(err) - defer conn.Close() + c := utils.SocketCall{} - _, err = conn.Write([]byte(conn.LocalAddr().String() + "here")) - errCheck(err) + c.SendData("hello") } // Listen timeout diff --git a/client/golang/go.mod b/client/golang/go.mod index 6d94347..0cd0963 100644 --- a/client/golang/go.mod +++ b/client/golang/go.mod @@ -2,6 +2,15 @@ module client go 1.18 -require github.com/google/gopacket v1.1.19 +require ( + github.com/google/gopacket v1.1.19 + github.com/mdlayher/packet v1.1.1 +) -require golang.org/x/sys v0.0.0-20190412213103-97732733099d // indirect +require ( + github.com/josharian/native v1.0.0 // indirect + github.com/mdlayher/socket v0.4.0 // indirect + golang.org/x/net v0.2.0 // indirect + golang.org/x/sync v0.1.0 // indirect + golang.org/x/sys v0.2.0 // indirect +) diff --git a/client/golang/go.sum b/client/golang/go.sum index a915606..d5145cb 100644 --- a/client/golang/go.sum +++ b/client/golang/go.sum @@ -1,5 +1,11 @@ github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= +github.com/josharian/native v1.0.0 h1:Ts/E8zCSEsG17dUqv7joXJFybuMLjQfWE04tsBODTxk= +github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= +github.com/mdlayher/packet v1.1.1 h1:7Fv4OEMYqPl7//uBm04VgPpnSNi8fbBZznppgh6WMr8= +github.com/mdlayher/packet v1.1.1/go.mod h1:DRvYY5mH4M4lUqAnMg04E60U4fjUKMZ/4g2cHElZkKo= +github.com/mdlayher/socket v0.4.0 h1:280wsy40IC9M9q1uPGcLBwXpcTQDtoGwVt+BNoITxIw= +github.com/mdlayher/socket v0.4.0/go.mod h1:xxFqz5GRCUN3UEOm9CZqEJsAbe1C8OwSK46NlmWuVoc= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= @@ -7,10 +13,16 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/client/golang/structs/file_transfer.go b/client/golang/structs/file_transfer.go new file mode 100644 index 0000000..abab9da --- /dev/null +++ b/client/golang/structs/file_transfer.go @@ -0,0 +1,21 @@ +package structs + +import ( +) + +type SaprusFileTransfer struct { + Flag [1]byte + Sequence [2]byte + Checksum [2]byte + Payload []byte +} + +func (c SaprusFileTransfer) Bytes() []byte { + data := []byte{} + data = append(data, c.Flag[0]) + data = append(data, c.Sequence[0], c.Sequence[1]) + data = append(data, c.Checksum[0], c.Checksum[1]) + data = append(data, c.Payload...) + return data +} + diff --git a/client/golang/structs/message.go b/client/golang/structs/message.go new file mode 100644 index 0000000..9459a56 --- /dev/null +++ b/client/golang/structs/message.go @@ -0,0 +1,21 @@ +package structs + +import ( +) + +type SaprusClientMessage struct { + Flag [1]byte + Sequence [2]byte + Checksum [2]byte + Payload []byte +} + +func (c SaprusClientMessage) Bytes() []byte { + data := []byte{} + data = append(data, c.Flag[0]) + data = append(data, c.Sequence[0], c.Sequence[1]) + data = append(data, c.Checksum[0], c.Checksum[1]) + data = append(data, c.Payload...) + return data +} + diff --git a/client/golang/structs/saprus.go b/client/golang/structs/saprus.go new file mode 100644 index 0000000..6e253d7 --- /dev/null +++ b/client/golang/structs/saprus.go @@ -0,0 +1,18 @@ +package structs + +import ( +) + +type SaprusHeaderFrame struct { + PacketType [2]byte + Length [2]byte + Payload []byte +} + +func (c SaprusHeaderFrame) Bytes() []byte { + data := []byte{} + data = append(data, c.PacketType[0], c.PacketType[1]) + data = append(data, c.Length[0], c.Length[1]) + data = append(data, c.Payload...) + return data +} diff --git a/client/golang/utils/file_transfer.go b/client/golang/utils/file_transfer.go new file mode 100644 index 0000000..287a511 --- /dev/null +++ b/client/golang/utils/file_transfer.go @@ -0,0 +1,92 @@ +package utils + +import ( + "log" + + "github.com/google/gopacket" + + "client/structs" +) + +func (c*SocketCall) BuildFileTransferPacket(Header structs.SaprusHeaderFrame, + Data structs.SaprusFileTransfer) gopacket.SerializeBuffer { + eth, ip, udp := basePacket(c) + + sapHeader := structs.SaprusHeaderFrame { + PacketType: Header.PacketType, + Length: c.saprusPayloadLength(Data.Bytes()), + Payload: Data.Bytes(), + } + + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions { + ComputeChecksums: true, + FixLengths: true, + } + + udp.SetNetworkLayerForChecksum(&ip) + err := gopacket.SerializeLayers(buf, opts, ð, &ip, &udp, gopacket.Payload(sapHeader.Bytes())) + + if err != nil { + log.Panic(err) + } + + return buf +} + +func (c* SocketCall) FileTransferPacket(message string, seqNum uint16) gopacket.SerializeBuffer { + sapFile := structs.SaprusFileTransfer { + Flag: [1]byte{0x11}, + Sequence: [2]byte{byte(seqNum >> 8), byte(seqNum & 0xFF)}, + Checksum: [2]byte{0x44, 0x44}, + Payload: []byte(message), + } + + sapHeader := structs.SaprusHeaderFrame { + PacketType: [2]byte{0x88, 0x88}, + Length: c.saprusPayloadLength(sapFile.Bytes()), + Payload: sapFile.Bytes(), + } + + buf := c.BuildFileTransferPacket(sapHeader, sapFile) + + return buf +} + +func (c* SocketCall) InitFileTransferPacket() gopacket.SerializeBuffer { + sapFile := structs.SaprusFileTransfer { + Flag: [1]byte{0x01}, + Sequence: [2]byte{0x00, 0x00}, + Checksum: [2]byte{0x00, 0x00}, + Payload: []byte{}, + } + + sapHeader := structs.SaprusHeaderFrame { + PacketType: [2]byte{0x00, 0x00}, + Length: c.saprusPayloadLength(sapFile.Bytes()), + Payload: sapFile.Bytes(), + } + + buf := c.BuildFileTransferPacket(sapHeader, sapFile) + + return buf +} + +func (c* SocketCall) EndFileTransferPacket() gopacket.SerializeBuffer { + sapFile := structs.SaprusFileTransfer { + Flag: [1]byte{0x02}, + Sequence: [2]byte{0x00, 0x00}, + Checksum: [2]byte{0x00, 0x00}, + Payload: []byte{}, + } + + sapHeader := structs.SaprusHeaderFrame { + PacketType: [2]byte{0x00, 0x00}, + Length: c.saprusPayloadLength(sapFile.Bytes()), + Payload: sapFile.Bytes(), + } + + buf := c.BuildFileTransferPacket(sapHeader, sapFile) + + return buf +} diff --git a/client/golang/utils/packet_helper.go b/client/golang/utils/packet_helper.go new file mode 100644 index 0000000..2f6b76a --- /dev/null +++ b/client/golang/utils/packet_helper.go @@ -0,0 +1,27 @@ +package utils + +import ( + "github.com/google/gopacket/layers" +) + +func basePacket(c* SocketCall) (layers.Ethernet, layers.IPv4, layers.UDP) { + 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: 8850, + DstPort: 8888, + } + + return eth, ip, udp +} + diff --git a/client/golang/utils/raw.go b/client/golang/utils/raw.go new file mode 100644 index 0000000..c85db19 --- /dev/null +++ b/client/golang/utils/raw.go @@ -0,0 +1,88 @@ +package utils + +import ( + "encoding/binary" + "log" + "time" + + "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{} + maxPacketLength := 1449 + + 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 GetAdapter() string { + inetInterface := "" + inetInterfaces, _ := net.Interfaces() + if inetInterfaces[0].Name == "lo" { + inetInterface = inetInterfaces[1].Name + } else { + inetInterface = inetInterfaces[0].Name + } + return inetInterface +} + +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(GetAdapter()) + c.Iface = iface + + conn, err := packet.Listen(iface, packet.Raw, int(layers.EthernetTypeIPv4), nil) + c.conn = conn + + if err != nil { + log.Panic(err) + } + + splitMessage := splitData(message) + + for i := 0; i < len(splitMessage); i++ { + c.SendPackage(c.FileTransferPacket(splitMessage[i], uint16(i))) + time.Sleep(20 * time.Microsecond) + + time.Sleep(200 * time.Microsecond) + + 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 +} + diff --git a/server/README.md b/server/README.md index 949d45e..652af7c 100644 --- a/server/README.md +++ b/server/README.md @@ -49,3 +49,17 @@ Saprus Type: 0x88 0x88 | Payload | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` + +## hold + +Saprus Type: 0x00 0x3C + +``` + 0 1 2 3 4 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Dest | | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +| Payload | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +``` diff --git a/server/server.go b/server/server.go index a31b9c9..1941974 100644 --- a/server/server.go +++ b/server/server.go @@ -1,18 +1,15 @@ package main import ( - "encoding/base64" "fmt" - "io/ioutil" "log" "net" - "strings" "saprusserver/utils" ) func welcomeMessage() { - msg :=`Welcome to -- + msg :=` ██████ ▄▄▄ ██▓███ ██▀███ █ ██ ██████ ▒██ ▒ ▒████▄ ▓██░ ██▒▓██ ▒ ██▒ ██ ▓██▒▒██ ▒ ░ ▓██▄ ▒██ ▀█▄ ▓██░ ██▓▒▓██ ░▄█ ▒▓██ ▒██░░ ▓██▄ @@ -36,15 +33,9 @@ func checkError(err error) { func main() { welcomeMessage() - log.Printf("Starting server\n") - con := utils.SocketCall{} - serv, err := net.ListenPacket("udp4", ":8888") - serverIP := "aaa" - msg := "clientapi: " + serverIP - fileBuf, _ := ioutil.ReadFile("./script.sh") - msg = string(fileBuf) - b64Msg := base64.StdEncoding.EncodeToString([]byte(msg)) + log.Println("Starting server") + serv, err := net.ListenPacket("udp4", ":8888") checkError(err) defer serv.Close() @@ -53,17 +44,8 @@ func main() { for { _, addr, err := serv.ReadFrom(buff) - checkError(err) - remoteAddr := strings.Split(addr.String(), ":") - - log.Printf("Received data %s\n", remoteAddr) - - checkError(err) - - con.SendData(b64Msg) - - log.Printf("Sending data to %s\n", addr) + go utils.ProcessRequests(buff, addr) } } diff --git a/server/structs/saprus.go b/server/structs/saprus.go index 58a6999..e2d97a2 100644 --- a/server/structs/saprus.go +++ b/server/structs/saprus.go @@ -3,6 +3,14 @@ package structs import ( ) +type UDPPackage struct { + SourcePort [2]byte + Destport [2]byte + Length [2]byte + Checksum [2]byte + +} + type SaprusHeaderFrame struct { PacketType [2]byte Length [2]byte @@ -16,4 +24,3 @@ func (c SaprusHeaderFrame) Bytes() []byte { data = append(data, c.Payload...) return data } - diff --git a/server/utils/service.go b/server/utils/service.go index 4b267fe..ffb1c55 100644 --- a/server/utils/service.go +++ b/server/utils/service.go @@ -1,6 +1,44 @@ package utils import ( + "encoding/base64" + "log" + "net" + "strings" + "saprusserver/structs" ) +func (c *SocketCall) GatherSaprusHeader(buf []byte) structs.SaprusHeaderFrame { + data := structs.SaprusHeaderFrame { + PacketType: [2]byte{buf[0], buf[1]}, + Length: [2]byte{buf[2], buf[3]}, + } + return data +} + +func ProcessRequests(buf []byte, addr net.Addr) { + c := SocketCall{} + + msg := "hello world" + b64Msg := base64.StdEncoding.EncodeToString([]byte(msg)) + + saprusHeader := c.GatherSaprusHeader(buf) + + remoteAddr := strings.Split(addr.String(), ":") + + switch { + case strings.Contains(string(buf), "here"): + log.Printf("Sending Data to %s\n", remoteAddr) + c.SendData(b64Msg) + case saprusHeader.PacketType == [2]byte{0x88, 0x88}: + log.Printf("New find:: %s\n", remoteAddr) + c.SendData(base64.StdEncoding.EncodeToString([]byte("hello\n"))) + case saprusHeader.PacketType == [2]byte{0x00, 0x3C}: + log.Printf("Broadcast message::%s\n", remoteAddr) + default: + log.Printf("Packet type not found::%x\n", string(saprusHeader.PacketType[:])) + } + + return +}