182 lines
3.5 KiB
Go
182 lines
3.5 KiB
Go
package packet
|
|
|
|
import (
|
|
"crypto/sha1"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"io/fs"
|
|
"os"
|
|
)
|
|
|
|
// FieldValue implements protocol.ProtocolFieldReferencer
|
|
type FieldValue struct {
|
|
Field string
|
|
FieldNum int
|
|
|
|
Value string
|
|
}
|
|
|
|
// GetProtocolField returns the protocol field
|
|
func (fv *FieldValue) GetProtocolField() (string, int) {
|
|
return fv.Field, fv.FieldNum
|
|
}
|
|
|
|
// SetProtocolField sets the protocl field
|
|
func (fv *FieldValue) SetProtocolField(f string, fn int) {
|
|
fv.Field = f
|
|
fv.FieldNum = fn
|
|
}
|
|
|
|
// SetValue sets the value
|
|
func (fv *FieldValue) SetValue(v string) {
|
|
fv.Value = v
|
|
}
|
|
|
|
// Layer implements protocol.ProtocolReferencer
|
|
type Layer struct {
|
|
ProtocolName string
|
|
Values []FieldValue
|
|
}
|
|
|
|
// Packet contains all layers of a packet and the data in different formats
|
|
type Packet struct {
|
|
MetaData Metadata
|
|
data []byte
|
|
Hex string
|
|
B64 string
|
|
Sha1 string
|
|
Layers []Layer
|
|
}
|
|
|
|
func NewPacketStructure() *Packet {
|
|
p := Packet{}
|
|
return &p
|
|
}
|
|
func UpdateMetaData(
|
|
pack *Packet,
|
|
) {
|
|
// still empty
|
|
}
|
|
|
|
func NewPacketLayer() *Layer {
|
|
p := Layer{}
|
|
return &p
|
|
}
|
|
|
|
func NewEmptyFieldValue() *FieldValue {
|
|
f := FieldValue{}
|
|
return &f
|
|
}
|
|
|
|
func NewFieldValue(
|
|
field string,
|
|
fieldnum int,
|
|
value string,
|
|
) *FieldValue {
|
|
f := FieldValue{
|
|
Value: value,
|
|
}
|
|
return &f
|
|
}
|
|
|
|
func (pack *Layer) AppendField(field *FieldValue) int {
|
|
i := len(pack.Values)
|
|
pack.Values = append(pack.Values, *field)
|
|
return i + 1
|
|
}
|
|
|
|
func (pack *Layer) AddField(index int, field *FieldValue) {
|
|
if len(pack.Values) == index {
|
|
pack.AppendField(field)
|
|
return
|
|
}
|
|
ret := make([]FieldValue, 0)
|
|
ret = append(ret, pack.Values[:index]...)
|
|
ret = append(ret, *field)
|
|
ret = append(ret, pack.Values[index:]...)
|
|
pack.Values = ret
|
|
}
|
|
|
|
func (pack *Packet) AppendLayer(layer *Layer) {
|
|
pack.Layers = append(pack.Layers, *layer)
|
|
}
|
|
|
|
func (pack *Packet) AddLayer(index int, layer *Layer) {
|
|
if len(pack.Layers) == index {
|
|
pack.AppendLayer(layer)
|
|
return
|
|
}
|
|
ret := make([]Layer, 0)
|
|
ret = append(ret, pack.Layers[:index]...)
|
|
ret = append(ret, *layer)
|
|
ret = append(ret, pack.Layers[index:]...)
|
|
pack.Layers = ret
|
|
}
|
|
|
|
func (pack *Layer) UpdateField(e int, field *FieldValue) {
|
|
pack.Values[e] = *field
|
|
}
|
|
|
|
func (pack *Packet) UpdateLayer(e int, layer *Layer) {
|
|
pack.Layers[e] = *layer
|
|
}
|
|
|
|
func (pack *Layer) RemoveField(e int) {
|
|
l := len(pack.Values) - 1
|
|
ret := make([]FieldValue, l)
|
|
ret = append(ret, pack.Values[:e]...)
|
|
ret = append(ret, pack.Values[e+1:]...)
|
|
pack.Values = ret
|
|
}
|
|
|
|
func (pack *Packet) RemoveLayer(e int) {
|
|
l := len(pack.Layers) - 1
|
|
ret := make([]Layer, l)
|
|
ret = append(ret, pack.Layers[:e]...)
|
|
ret = append(ret, pack.Layers[e+1:]...)
|
|
pack.Layers = ret
|
|
}
|
|
|
|
func (pack *Packet) Load(path string) error {
|
|
data, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = json.Unmarshal(data, pack)
|
|
pack.data, err = base64.StdEncoding.DecodeString(pack.B64)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if pack.Sha1 != fmt.Sprintf("%x", sha1.Sum(pack.data)) {
|
|
return errors.New("sha1sum does not match")
|
|
}
|
|
return err
|
|
}
|
|
|
|
func (pack *Packet) UpdateData() {
|
|
pack.Hex = fmt.Sprintf("%x", pack.data)
|
|
pack.B64 = base64.RawStdEncoding.EncodeToString(pack.data)
|
|
pack.Sha1 = fmt.Sprintf("%x", sha1.Sum(pack.data))
|
|
}
|
|
|
|
func (pack *Packet) ToJson() string {
|
|
pack.UpdateData()
|
|
data, err := json.MarshalIndent(*pack, "", " ")
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
return string(data)
|
|
}
|
|
|
|
func (pack *Packet) Save(path string) error {
|
|
pack.UpdateData()
|
|
data, err := json.MarshalIndent(*pack, "", " ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = os.WriteFile(path, data, fs.ModeAppend)
|
|
return err
|
|
}
|