147 lines
3.2 KiB
Go
147 lines
3.2 KiB
Go
package packer
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"net"
|
|
"strconv"
|
|
)
|
|
|
|
const (
|
|
packerV1 byte = 255 - 1
|
|
packerV2 byte = 255 - 2
|
|
)
|
|
|
|
//Packer -- contains both header and data
|
|
type Packer struct {
|
|
Header *packerHeader
|
|
Data *packerData
|
|
}
|
|
|
|
//NewPacker -- Structre
|
|
func NewPacker() (p *Packer) {
|
|
p = new(Packer)
|
|
p.Header = newPackerHeader()
|
|
p.Data = newPackerData()
|
|
return
|
|
}
|
|
|
|
//ReadMessage -
|
|
func ReadMessage(b []byte) (p *Packer, err error) {
|
|
fmt.Println("ReadMessage")
|
|
var pos int
|
|
|
|
err = nil
|
|
// detect protocol in use
|
|
if b[0] == packerV1 {
|
|
p = NewPacker()
|
|
|
|
// Handle Header Length
|
|
pos = pos + 1
|
|
p.Header.HeaderLen = b[pos]
|
|
|
|
//handle address family
|
|
pos = pos + 1
|
|
end := bytes.IndexAny(b[pos:], ",")
|
|
if end == -1 {
|
|
err = fmt.Errorf("missing , while parsing address family")
|
|
return nil, err
|
|
}
|
|
|
|
bAddrFamily := b[pos : pos+end]
|
|
if bytes.ContainsAny(bAddrFamily, addressFamilyText[FamilyIPv4]) {
|
|
p.Header.family = FamilyIPv4
|
|
} else if bytes.ContainsAny(bAddrFamily, addressFamilyText[FamilyIPv6]) {
|
|
p.Header.family = FamilyIPv6
|
|
} else {
|
|
err = fmt.Errorf("Address family not supported %d", bAddrFamily)
|
|
}
|
|
|
|
//handle address
|
|
pos = pos + end + 1
|
|
end = bytes.IndexAny(b[pos:], ",")
|
|
if end == -1 {
|
|
err = fmt.Errorf("missing , while parsing address")
|
|
return nil, err
|
|
}
|
|
p.Header.address = net.ParseIP(string(b[pos : pos+end]))
|
|
|
|
//handle import
|
|
pos = pos + end + 1
|
|
end = bytes.IndexAny(b[pos:], ",")
|
|
if end == -1 {
|
|
err = fmt.Errorf("missing , while parsing address")
|
|
return nil, err
|
|
}
|
|
|
|
p.Header.Port, err = strconv.Atoi(string(b[pos : pos+end]))
|
|
if err != nil {
|
|
err = fmt.Errorf("error converting port %s", err)
|
|
}
|
|
|
|
//handle data length
|
|
pos = pos + end + 1
|
|
end = bytes.IndexAny(b[pos:], ",")
|
|
if end == -1 {
|
|
err = fmt.Errorf("missing , while parsing address")
|
|
return nil, err
|
|
}
|
|
|
|
p.Data.DataLen, err = strconv.Atoi(string(b[pos : pos+end]))
|
|
if err != nil {
|
|
err = fmt.Errorf("error converting data length %s", err)
|
|
}
|
|
|
|
//handle Service
|
|
pos = pos + end + 1
|
|
end = pos + int(p.Header.HeaderLen)
|
|
p.Header.Service = string(b[pos : p.Header.HeaderLen+2])
|
|
|
|
//handle payload
|
|
pos = int(p.Header.HeaderLen + 2)
|
|
p.Data.AppendBytes(b[pos:])
|
|
|
|
} else {
|
|
err = fmt.Errorf("Version %d not supported", b[0:0])
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
//PackV1 -- Outputs version 1 of packer
|
|
func (p *Packer) PackV1() (b bytes.Buffer) {
|
|
version := packerV1
|
|
|
|
var headerBuf bytes.Buffer
|
|
headerBuf.WriteString(p.Header.FamilyText())
|
|
headerBuf.WriteString(",")
|
|
headerBuf.Write([]byte(p.Header.Address().String()))
|
|
headerBuf.WriteString(",")
|
|
headerBuf.WriteString(fmt.Sprintf("%d", p.Header.Port))
|
|
headerBuf.WriteString(",")
|
|
headerBuf.WriteString(fmt.Sprintf("%d", p.Data.buffer.Len()))
|
|
headerBuf.WriteString(",")
|
|
headerBuf.WriteString(p.Header.Service)
|
|
|
|
var metaBuf bytes.Buffer
|
|
metaBuf.WriteByte(version)
|
|
metaBuf.WriteByte(byte(headerBuf.Len()))
|
|
|
|
var buf bytes.Buffer
|
|
buf.Write(metaBuf.Bytes())
|
|
buf.Write(headerBuf.Bytes())
|
|
buf.Write(p.Data.buffer.Bytes())
|
|
|
|
//fmt.Println("header: ", headerBuf.String())
|
|
//fmt.Println("meta: ", metaBuf)
|
|
//fmt.Println("Data: ", p.Data.buffer)
|
|
//fmt.Println("Buffer: ", buf.Bytes())
|
|
//fmt.Println("Buffer: ", hex.Dump(buf.Bytes()))
|
|
//fmt.Printf("Buffer %s", buf.Bytes())
|
|
|
|
b = buf
|
|
|
|
return
|
|
}
|