mirror of
https://github.com/codewhitesec/Lastenzug
synced 2026-06-08 13:35:16 +00:00
93 lines
1.9 KiB
Go
93 lines
1.9 KiB
Go
package protocol
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"errors"
|
|
"io"
|
|
|
|
"github.com/c-f/talje/lib/kommando"
|
|
"github.com/c-f/talje/lib/ladung"
|
|
)
|
|
|
|
// Error Messages for handling with byte streams
|
|
var (
|
|
ErrMessageToSmall ErrParsing = errors.New("message to small")
|
|
ErrMessageBadLength ErrParsing = errors.New("bad length")
|
|
)
|
|
|
|
// ByteLadung creates bytestream Ladung
|
|
type Binary struct{}
|
|
|
|
// WritePacket encodes a Packet and writes it to a writer
|
|
func (bl *Binary) WritePacket(g ladung.Packet, w io.Writer) (err error) {
|
|
var bts []byte
|
|
|
|
session := []byte(g.SessionID)[0:8]
|
|
|
|
command := make([]byte, 8)
|
|
binary.LittleEndian.PutUint64(command, uint64(g.Kommando))
|
|
|
|
l := make([]byte, 8)
|
|
binary.LittleEndian.PutUint64(l, uint64(len(g.Message)))
|
|
|
|
// Create Protocol
|
|
// [ sess | komando | len(msg) | msg ]
|
|
bts = append(bts, session...)
|
|
bts = append(bts, command...)
|
|
bts = append(bts, l...)
|
|
bts = append(bts, g.Message...)
|
|
|
|
_, err = w.Write(bts)
|
|
return
|
|
}
|
|
|
|
// ReadPacket decodes a Packet from a reader
|
|
func (bl *Binary) ReadPacket(r io.Reader) (g ladung.Packet, err error) {
|
|
var n int
|
|
|
|
session := make([]byte, 8)
|
|
command := make([]byte, 8)
|
|
l := make([]byte, 8)
|
|
|
|
readVar := func(val []byte) error {
|
|
n, err = r.Read(val)
|
|
if err == nil && n != len(val) {
|
|
err = ErrMessageToSmall
|
|
}
|
|
return err
|
|
}
|
|
|
|
// Read Variables
|
|
if err = readVar(session); err != nil {
|
|
return
|
|
}
|
|
if err = readVar(command); err != nil {
|
|
return
|
|
}
|
|
if err = readVar(l); err != nil {
|
|
return
|
|
}
|
|
|
|
length := int(binary.LittleEndian.Uint64(l))
|
|
if length < 0 || length >= 100000 {
|
|
err = ErrMessageBadLength
|
|
return
|
|
}
|
|
msg := make([]byte, length)
|
|
if err = readVar(msg); err != nil {
|
|
return
|
|
}
|
|
|
|
// Stitch together
|
|
g.SessionID = string(session)
|
|
g.Kommando = kommando.Code(BytesToInt(command))
|
|
g.Message = msg
|
|
|
|
return
|
|
}
|
|
|
|
// BytesToInt converts byte to int
|
|
func BytesToInt(bts []byte) int {
|
|
return int(binary.LittleEndian.Uint64(bts))
|
|
}
|