Work on collection of protocols and requirements
This commit is contained in:
parent
608122e5a1
commit
09d4b338d2
|
@ -0,0 +1,164 @@
|
||||||
|
package cop
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"os/user"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/go-git/go-git/v5"
|
||||||
|
|
||||||
|
"gitea.mmo.to/ppForge/ppforge/protocol"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ProtocolCollectionList is a list of all databases, with the most simple interface
|
||||||
|
type ProtocolCollectionList struct {
|
||||||
|
PCs []COP
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProtocolCollectionEntry is a single entry in the file database, additionally to the meta data the path is required
|
||||||
|
type ProtocolCollectionEntry struct {
|
||||||
|
Path string
|
||||||
|
Protocol protocol.ProtocolMeta
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init initializes the databases, opens the default one and checks for others if available
|
||||||
|
func Init() *ProtocolCollectionList {
|
||||||
|
// initialize main list
|
||||||
|
databases := ProtocolCollectionList{[]COP{}}
|
||||||
|
// initialize default db
|
||||||
|
user, err := user.Current()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Current user not obtainable: %s", err)
|
||||||
|
log.Fatal("Impossible to open default database")
|
||||||
|
}
|
||||||
|
pathlist := []string{user.HomeDir, ".config", "ppforge"}
|
||||||
|
fdb := FileCOP{COP{map[string]ProtocolCollectionEntry{}, false}, path.Join(pathlist...)}
|
||||||
|
fdb.Open(path.Join(pathlist...))
|
||||||
|
fdb.UpdateCollection()
|
||||||
|
databases.PCs = append(databases.PCs, fdb.COP)
|
||||||
|
log.Printf("Amount of databases available %d", len(databases.PCs))
|
||||||
|
return &databases
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a full protocol from a database entry
|
||||||
|
func (de *ProtocolCollectionEntry) Get() (*protocol.Protocol, error) {
|
||||||
|
return protocol.LoadNew(de.Path)
|
||||||
|
}
|
||||||
|
|
||||||
|
// COP represents a Collection of Protocols
|
||||||
|
type COP struct {
|
||||||
|
protocols map[string]ProtocolCollectionEntry
|
||||||
|
closed bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileCOP implements
|
||||||
|
type FileCOP struct {
|
||||||
|
COP
|
||||||
|
Path string
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileCOPFromGitRemote implements retrieving the latest stuff from an external git remote additionally to the FileDatabase functionality
|
||||||
|
type FileCOPFromGitRemote struct {
|
||||||
|
FileCOP
|
||||||
|
RemoteGitRepository string
|
||||||
|
gitRepo git.Repository
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open the database
|
||||||
|
func (fd *FileCOP) Open(path string) error {
|
||||||
|
fileinfo, err := os.Stat(path)
|
||||||
|
if err == os.ErrNotExist {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !fileinfo.IsDir() {
|
||||||
|
return fmt.Errorf("Path %s is not a directory", path)
|
||||||
|
}
|
||||||
|
fd.Path = path
|
||||||
|
fd.closed = false
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close the database and free the data
|
||||||
|
func (fd *FileCOP) Close() error {
|
||||||
|
fd.closed = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Protocols returns the map of protocols or an error if the first read failed
|
||||||
|
func (fd *FileCOP) Protocols() ([]ProtocolCollectionEntry, error) {
|
||||||
|
if fd.closed {
|
||||||
|
return nil, errors.New("COP closed, no protocols to deliver")
|
||||||
|
}
|
||||||
|
entries := []ProtocolCollectionEntry{}
|
||||||
|
if !fd.closed && len(fd.protocols) == 0 {
|
||||||
|
fd.protocols = map[string]ProtocolCollectionEntry{}
|
||||||
|
err := fd.UpdateCollection()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if entries == nil || len(entries) == 0 {
|
||||||
|
entries = make([]ProtocolCollectionEntry, 0)
|
||||||
|
for _, v := range fd.protocols {
|
||||||
|
entries = append(entries, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return entries, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add puts a new protocol into the path of the file database
|
||||||
|
func (fd *FileCOP) Add(prot *protocol.Protocol) error {
|
||||||
|
if fd.closed {
|
||||||
|
return errors.New("Cannot add, FileCOP is closed")
|
||||||
|
}
|
||||||
|
p := path.Join(fd.Path, prot.Metadata.Name, ".protocoljson")
|
||||||
|
err := prot.Save(p)
|
||||||
|
if err == nil {
|
||||||
|
fd.protocols[prot.Metadata.Name] = ProtocolCollectionEntry{p, prot.Metadata}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update updates an existing entry through saving the contents of the protocol to the file, or just adding it anew
|
||||||
|
func (fd *FileCOP) Update(prot *protocol.Protocol) error {
|
||||||
|
if fd.closed {
|
||||||
|
return errors.New("Cannot update, FileCOP is closed")
|
||||||
|
}
|
||||||
|
if v, ok := fd.protocols[prot.Metadata.Name]; ok {
|
||||||
|
v.Protocol = prot.Metadata
|
||||||
|
return prot.Save(v.Path)
|
||||||
|
}
|
||||||
|
return fd.Add(prot)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateCollection just rereads all files
|
||||||
|
func (fd *FileCOP) UpdateCollection() error {
|
||||||
|
if fd.closed {
|
||||||
|
return errors.New("Cannot update, FileCOP is closed")
|
||||||
|
}
|
||||||
|
// recurse recursively through the path
|
||||||
|
if fd.protocols == nil {
|
||||||
|
fd.protocols = make(map[string]ProtocolCollectionEntry)
|
||||||
|
}
|
||||||
|
err := filepath.Walk(fd.Path, func(path string, info fs.FileInfo, err error) error {
|
||||||
|
if !info.IsDir() && strings.HasSuffix(info.Name(), ".protocoljson") {
|
||||||
|
prot, err := protocol.LoadNew(path)
|
||||||
|
if err == nil {
|
||||||
|
// add to map
|
||||||
|
// add to map
|
||||||
|
entry := ProtocolCollectionEntry{path, prot.Metadata}
|
||||||
|
|
||||||
|
fd.protocols[prot.Metadata.Name] = entry
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
package cop
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestOpen(t *testing.T) {
|
||||||
|
fcop := FileCOP{}
|
||||||
|
wd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Os error: %s", err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
fcop.Open(path.Join(wd, "..", "test", "cop"))
|
||||||
|
l, err := fcop.Protocols()
|
||||||
|
if err != nil {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
for k, v := range fcop.protocols {
|
||||||
|
fmt.Printf("%s->%s\n", k, v.Path)
|
||||||
|
}
|
||||||
|
for _, pce := range l {
|
||||||
|
fmt.Printf("%s//%s\n", pce.Path, pce.Protocol.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClosed(t *testing.T) {
|
||||||
|
fcop := FileCOP{}
|
||||||
|
wd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Os error: %s", err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
fcop.Open(path.Join(wd, "..", "test", "cop"))
|
||||||
|
fcop.Close()
|
||||||
|
l, err := fcop.Protocols()
|
||||||
|
if err == nil || l != nil {
|
||||||
|
fmt.Println("Protocols did not deliver error")
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
err = fcop.Add(nil)
|
||||||
|
if err == nil {
|
||||||
|
fmt.Println("Add did not deliver error")
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
err = fcop.Update(nil)
|
||||||
|
if err == nil {
|
||||||
|
fmt.Println("Update did not deliver error")
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
err = fcop.UpdateCollection()
|
||||||
|
if err == nil {
|
||||||
|
fmt.Println("UpdateCollection did not deliver error")
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,179 +0,0 @@
|
||||||
package dop
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io/fs"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"os/user"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/go-git/go-git/v5"
|
|
||||||
|
|
||||||
"gitea.mmo.to/ppForge/ppforge/protocol"
|
|
||||||
"gitea.mmo.to/ppForge/ppforge/protocolctl"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ProtocolDictionaryList is a list of all databases, with the most simple interface
|
|
||||||
type ProtocolDictionaryList struct {
|
|
||||||
PDs []ProtocolDictionaryProvider
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProtocolDictionaryProvider is a simple protocol database interface, which only provides open/close and retrieving the contents
|
|
||||||
type ProtocolDictionaryProvider interface {
|
|
||||||
// Open opens a new database
|
|
||||||
Open(path string) error
|
|
||||||
// Close closes a database (only internal flag set)
|
|
||||||
Close() error
|
|
||||||
// Protocols returns the content of the database as map, an error if the first read of the database failed
|
|
||||||
Protocols() ([]ProtocolDictionaryEntry, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProtocolDatabaseManager is a complex protocol database interface, which allows adding, updating and refreshing of the content
|
|
||||||
type ProtocolDatabaseManager interface {
|
|
||||||
Add(prot *protocol.ProtocolStructure) error
|
|
||||||
Update(prot *protocol.ProtocolStructure) error
|
|
||||||
// no remove.
|
|
||||||
UpdateDatabase() error // scans for new protocols
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProtocolDictionaryEntry is a single entry in the file database, additionally to the meta data the path is required
|
|
||||||
type ProtocolDictionaryEntry struct {
|
|
||||||
Path string
|
|
||||||
Protocol protocol.DOPMeta
|
|
||||||
}
|
|
||||||
|
|
||||||
// Init initializes the databases, opens the default one and checks for others if available
|
|
||||||
func Init() *ProtocolDictionaryList {
|
|
||||||
// initialize main list
|
|
||||||
databases := ProtocolDictionaryList{[]ProtocolDictionaryProvider{}}
|
|
||||||
// initialize default db
|
|
||||||
user, err := user.Current()
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Current user not obtainable: %s", err)
|
|
||||||
log.Fatal("Impossible to open default database")
|
|
||||||
}
|
|
||||||
pathlist := []string{user.HomeDir, ".config", "ppforge"}
|
|
||||||
fdb := FileDOP{path.Join(pathlist...), map[string]ProtocolDictionaryEntry{}, false}
|
|
||||||
fdb.Open(path.Join(pathlist...))
|
|
||||||
fdb.UpdateDatabase()
|
|
||||||
databases.PDs = append(databases.PDs, fdb)
|
|
||||||
log.Printf("Amount of databases available %d", len(databases.PDs))
|
|
||||||
return &databases
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get Retrieves the full set of databases
|
|
||||||
func (ppfdb *ProtocolDictionaryList) Get() []ProtocolDictionaryProvider {
|
|
||||||
return ppfdb.PDs
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get a full protocol from a database entry
|
|
||||||
func (de *ProtocolDictionaryEntry) Get() (*protocol.ProtocolStructure, error) {
|
|
||||||
return protocolctl.LoadNew(de.Path)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FileDOP implements ProtocolDatabaseProvider and ProtocolDatabaseManager
|
|
||||||
type FileDOP struct {
|
|
||||||
Path string
|
|
||||||
protocols map[string]ProtocolDictionaryEntry
|
|
||||||
closed bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// FileDOPFromGitRemote implements retrieving the latest stuff from an external git remote additionally to the FileDatabase functionality
|
|
||||||
// TODO
|
|
||||||
type FileDOPFromGitRemote struct {
|
|
||||||
FileDOP
|
|
||||||
RemoteGitRepository string
|
|
||||||
gitRepo git.Repository
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open the database
|
|
||||||
func (fd FileDOP) Open(path string) error {
|
|
||||||
fileinfo, err := os.Stat(path)
|
|
||||||
if err == os.ErrNotExist {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if !fileinfo.IsDir() {
|
|
||||||
return fmt.Errorf("Path %s is not a directory", path)
|
|
||||||
}
|
|
||||||
fd.Path = path
|
|
||||||
fd.closed = false
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close the database and free the data
|
|
||||||
func (fd FileDOP) Close() error {
|
|
||||||
for k := range fd.protocols {
|
|
||||||
delete(fd.protocols, k)
|
|
||||||
}
|
|
||||||
fd.closed = true
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Protocols returns the map of protocols or an error if the first read failed
|
|
||||||
func (fd FileDOP) Protocols() ([]ProtocolDictionaryEntry, error) {
|
|
||||||
entries := []ProtocolDictionaryEntry{}
|
|
||||||
if !fd.closed && len(fd.protocols) == 0 {
|
|
||||||
fd.protocols = map[string]ProtocolDictionaryEntry{}
|
|
||||||
// recurse recursively through the path
|
|
||||||
err := filepath.Walk(fd.Path, func(path string, info fs.FileInfo, err error) error {
|
|
||||||
if !info.IsDir() {
|
|
||||||
prot, err := protocolctl.LoadNew(path)
|
|
||||||
if err == nil {
|
|
||||||
// add to map
|
|
||||||
entry := ProtocolDictionaryEntry{path, prot.Metadata}
|
|
||||||
|
|
||||||
fd.protocols[prot.Metadata.Name] = entry
|
|
||||||
entries = append(entries, entry)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if entries == nil || len(entries) == 0 {
|
|
||||||
entries = make([]ProtocolDictionaryEntry, len(fd.protocols))
|
|
||||||
for _, v := range fd.protocols {
|
|
||||||
entries = append(entries, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return entries, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add puts a new protocol into the path of the file database
|
|
||||||
func (fd *FileDOP) Add(prot *protocol.ProtocolStructure) error {
|
|
||||||
p := path.Join(fd.Path, prot.Metadata.Name, ".protocoljson")
|
|
||||||
err := protocolctl.Save(prot, p)
|
|
||||||
if err == nil {
|
|
||||||
fd.protocols[prot.Metadata.Name] = ProtocolDictionaryEntry{p, prot.Metadata}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update updates an existing entry through saving the contents of the protocol to the file, or just adding it anew
|
|
||||||
func (fd *FileDOP) Update(prot *protocol.ProtocolStructure) error {
|
|
||||||
if v, ok := fd.protocols[prot.Metadata.Name]; ok {
|
|
||||||
v.Protocol = prot.Metadata
|
|
||||||
return protocolctl.Save(prot, v.Path)
|
|
||||||
}
|
|
||||||
return fd.Add(prot)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateDatabase just rereads all files
|
|
||||||
func (fd *FileDOP) UpdateDatabase() error {
|
|
||||||
// recurse recursively through the path
|
|
||||||
err := filepath.Walk(fd.Path, func(path string, info fs.FileInfo, err error) error {
|
|
||||||
if !info.IsDir() {
|
|
||||||
prot, err := protocolctl.LoadNew(path)
|
|
||||||
if err == nil {
|
|
||||||
// add to map
|
|
||||||
fd.protocols[prot.Metadata.Name] = ProtocolDictionaryEntry{path, prot.Metadata}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
return err
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
package dop
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test(t *testing.T) {
|
|
||||||
|
|
||||||
}
|
|
|
@ -88,7 +88,7 @@ func NewMetadataProtocol() *ProtocolMetadata {
|
||||||
return &md
|
return &md
|
||||||
}
|
}
|
||||||
|
|
||||||
func (md *ProtocolMetadata) SetProtocol(prot *protocol.ProtocolStructure) {
|
func (md *ProtocolMetadata) SetProtocol(prot *protocol.Protocol) {
|
||||||
setfunc := func(s string) {
|
setfunc := func(s string) {
|
||||||
protocolctl.UpdateMetaData(
|
protocolctl.UpdateMetaData(
|
||||||
prot,
|
prot,
|
||||||
|
@ -105,7 +105,6 @@ func (md *ProtocolMetadata) SetProtocol(prot *protocol.ProtocolStructure) {
|
||||||
md.VersionValue.SetText(prot.Metadata.Version)
|
md.VersionValue.SetText(prot.Metadata.Version)
|
||||||
md.DescValue.SetText(prot.Metadata.Description)
|
md.DescValue.SetText(prot.Metadata.Description)
|
||||||
md.ExtendsValue.SetText(prot.Metadata.ExtensionTo)
|
md.ExtendsValue.SetText(prot.Metadata.ExtensionTo)
|
||||||
md.OsiLayer.SetSelectedIndex(int(prot.Metadata.OSILayer))
|
|
||||||
md.TcpIpLayer.SetSelectedIndex(int(prot.Metadata.TCPIPLayer))
|
md.TcpIpLayer.SetSelectedIndex(int(prot.Metadata.TCPIPLayer))
|
||||||
md.SetChanged(setfunc)
|
md.SetChanged(setfunc)
|
||||||
md.Representation.Refresh()
|
md.Representation.Refresh()
|
||||||
|
@ -115,7 +114,7 @@ func (md *ProtocolMetadata) Unset() {
|
||||||
md.SetChanged(func(s string) {})
|
md.SetChanged(func(s string) {})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (md *PacketMetadata) SetData(pack *packet.Structure) {
|
func (md *PacketMetadata) SetData(pack *packet.Packet) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,10 +17,10 @@ type PacketEditor struct {
|
||||||
|
|
||||||
ShowShortHints bool
|
ShowShortHints bool
|
||||||
|
|
||||||
Reference *packet.Structure
|
Reference *packet.Packet
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPacketEditor(ref *packet.Structure) *PacketEditor {
|
func NewPacketEditor(ref *packet.Packet) *PacketEditor {
|
||||||
metadata := NewMetadataPacket()
|
metadata := NewMetadataPacket()
|
||||||
fields := container.NewGridWrap(fyne.NewSize(300, 200))
|
fields := container.NewGridWrap(fyne.NewSize(300, 200))
|
||||||
container := container.NewBorder(nil, nil, metadata.Representation, nil, container.NewVScroll(fields))
|
container := container.NewBorder(nil, nil, metadata.Representation, nil, container.NewVScroll(fields))
|
||||||
|
|
|
@ -39,9 +39,9 @@ func CreatePacketFieldEditor(
|
||||||
|
|
||||||
elements := []fyne.CanvasObject{}
|
elements := []fyne.CanvasObject{}
|
||||||
|
|
||||||
elements = append(elements, widget.NewLabel(ref.GetProtocolField().Name))
|
elements = append(elements, widget.NewLabel("TODO"))
|
||||||
if ed.ShowShortHints {
|
if ed.ShowShortHints {
|
||||||
elements = append(elements, widget.NewLabel(ref.GetProtocolField().Regex)) // todo: implement real shorthints if feasible
|
elements = append(elements, widget.NewLabel("TODO")) // todo: implement real shorthints if feasible
|
||||||
}
|
}
|
||||||
|
|
||||||
// depending on the input stuff, entry for now
|
// depending on the input stuff, entry for now
|
||||||
|
|
|
@ -14,7 +14,7 @@ type PacketFileHandler struct {
|
||||||
changed bool
|
changed bool
|
||||||
tab *container.TabItem
|
tab *container.TabItem
|
||||||
|
|
||||||
Reference *packet.Structure
|
Reference *packet.Packet
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPacketFileHandler() *PacketFileHandler {
|
func NewPacketFileHandler() *PacketFileHandler {
|
||||||
|
|
|
@ -15,10 +15,10 @@ type ProtocolEditor struct {
|
||||||
Metadata *ProtocolMetadata
|
Metadata *ProtocolMetadata
|
||||||
Fields []*FieldEditor
|
Fields []*FieldEditor
|
||||||
|
|
||||||
Reference *protocol.ProtocolStructure
|
Reference *protocol.Protocol
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewProtocolEditor(ref *protocol.ProtocolStructure) *ProtocolEditor {
|
func NewProtocolEditor(ref *protocol.Protocol) *ProtocolEditor {
|
||||||
metadata := NewMetadataProtocol()
|
metadata := NewMetadataProtocol()
|
||||||
fields := container.NewGridWrap(fyne.NewSize(300, 400))
|
fields := container.NewGridWrap(fyne.NewSize(300, 400))
|
||||||
container := container.NewBorder(nil, nil, metadata.Representation, nil, container.NewVScroll(fields))
|
container := container.NewBorder(nil, nil, metadata.Representation, nil, container.NewVScroll(fields))
|
||||||
|
|
|
@ -17,7 +17,7 @@ type ProtocolFileHandler struct {
|
||||||
changed bool
|
changed bool
|
||||||
tab *container.TabItem
|
tab *container.TabItem
|
||||||
|
|
||||||
Reference *protocol.ProtocolStructure
|
Reference *protocol.Protocol
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewProtocolFileHandler() *ProtocolFileHandler {
|
func NewProtocolFileHandler() *ProtocolFileHandler {
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
package packet
|
|
||||||
|
|
||||||
import "gitea.mmo.to/ppForge/ppforge/protocol"
|
|
||||||
|
|
||||||
// FieldValue implements protocol.ProtocolFieldReferencer
|
|
||||||
type FieldValue struct {
|
|
||||||
fieldReference *protocol.Field
|
|
||||||
|
|
||||||
Value string
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetProtocolField returns the protocol field
|
|
||||||
func (fv *FieldValue) GetProtocolField() *protocol.Field {
|
|
||||||
return fv.fieldReference
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetProtocolField sets the protocl field
|
|
||||||
func (fv *FieldValue) SetProtocolField(pf *protocol.Field) {
|
|
||||||
fv.fieldReference = pf
|
|
||||||
}
|
|
175
packet/packet.go
175
packet/packet.go
|
@ -1,26 +1,181 @@
|
||||||
package packet
|
package packet
|
||||||
|
|
||||||
import "gitea.mmo.to/ppForge/ppforge/protocol"
|
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
|
// Layer implements protocol.ProtocolReferencer
|
||||||
type Layer struct {
|
type Layer struct {
|
||||||
// needs a reference to a protocol
|
|
||||||
protocolReference *protocol.ProtocolStructure
|
|
||||||
|
|
||||||
ProtocolName string
|
ProtocolName string
|
||||||
Values []FieldValue
|
Values []FieldValue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Structure contains all layers of a packet
|
// Packet contains all layers of a packet and the data in different formats
|
||||||
type Structure struct {
|
type Packet struct {
|
||||||
MetaData Metadata
|
MetaData Metadata
|
||||||
|
data []byte
|
||||||
|
Hex string
|
||||||
|
B64 string
|
||||||
|
Sha1 string
|
||||||
Layers []Layer
|
Layers []Layer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pl *Layer) GetProtocol() *protocol.ProtocolStructure {
|
func NewPacketStructure() *Packet {
|
||||||
return pl.protocolReference
|
p := Packet{}
|
||||||
|
return &p
|
||||||
|
}
|
||||||
|
func UpdateMetaData(
|
||||||
|
pack *Packet,
|
||||||
|
) {
|
||||||
|
// still empty
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pl *Layer) Setprotocol(ps *protocol.ProtocolStructure) {
|
func NewPacketLayer() *Layer {
|
||||||
pl.protocolReference = ps
|
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
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package packet
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"gitea.mmo.to/ppForge/ppforge/protocol"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GenerateProtocol1() *protocol.Protocol {
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func GenerateProtocol2() *protocol.Protocol {
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBinaryGeneration(t *testing.T) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestJsonExport(t *testing.T) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestJsonImport(t *testing.T) {
|
||||||
|
|
||||||
|
}
|
|
@ -2,5 +2,6 @@ package packet
|
||||||
|
|
||||||
// Metadata struct is the absolute minimum of metadata
|
// Metadata struct is the absolute minimum of metadata
|
||||||
type Metadata struct {
|
type Metadata struct {
|
||||||
Name string
|
Name string
|
||||||
|
Revision int
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,123 +0,0 @@
|
||||||
package packetctl
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"io/fs"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"gitea.mmo.to/ppForge/ppforge/packet"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewPacketStructure() *packet.Structure {
|
|
||||||
p := packet.Structure{}
|
|
||||||
return &p
|
|
||||||
}
|
|
||||||
|
|
||||||
func UpdateMetaData(
|
|
||||||
pack *packet.Structure,
|
|
||||||
) {
|
|
||||||
// still empty
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewPacketLayer() *packet.Layer {
|
|
||||||
p := packet.Layer{}
|
|
||||||
return &p
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewEmptyFieldValue() *packet.FieldValue {
|
|
||||||
f := packet.FieldValue{}
|
|
||||||
return &f
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFieldValue(
|
|
||||||
value string,
|
|
||||||
) *packet.FieldValue {
|
|
||||||
f := packet.FieldValue{
|
|
||||||
Value: value,
|
|
||||||
}
|
|
||||||
return &f
|
|
||||||
}
|
|
||||||
|
|
||||||
func AppendField(pack *packet.Layer, field *packet.FieldValue) int {
|
|
||||||
i := len(pack.Values)
|
|
||||||
pack.Values = append(pack.Values, *field)
|
|
||||||
return i + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
func AddField(pack *packet.Layer, index int, field *packet.FieldValue) {
|
|
||||||
if len(pack.Values) == index {
|
|
||||||
AppendField(pack, field)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ret := make([]packet.FieldValue, 0)
|
|
||||||
ret = append(ret, pack.Values[:index]...)
|
|
||||||
ret = append(ret, *field)
|
|
||||||
ret = append(ret, pack.Values[index:]...)
|
|
||||||
pack.Values = ret
|
|
||||||
}
|
|
||||||
|
|
||||||
func AppendLayer(pack *packet.Structure, layer *packet.Layer) {
|
|
||||||
pack.Layers = append(pack.Layers, *layer)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Addlayer(pack *packet.Structure, index int, layer *packet.Layer) {
|
|
||||||
if len(pack.Layers) == index {
|
|
||||||
AppendLayer(pack, layer)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ret := make([]packet.Layer, 0)
|
|
||||||
ret = append(ret, pack.Layers[:index]...)
|
|
||||||
ret = append(ret, *layer)
|
|
||||||
ret = append(ret, pack.Layers[index:]...)
|
|
||||||
pack.Layers = ret
|
|
||||||
}
|
|
||||||
|
|
||||||
func UpdateField(pack *packet.Layer, e int, field *packet.FieldValue) {
|
|
||||||
pack.Values[e] = *field
|
|
||||||
}
|
|
||||||
|
|
||||||
func UpdateLayer(pack *packet.Structure, e int, layer *packet.Layer) {
|
|
||||||
pack.Layers[e] = *layer
|
|
||||||
}
|
|
||||||
|
|
||||||
func RemoveField(pack *packet.Layer, e int) {
|
|
||||||
l := len(pack.Values) - 1
|
|
||||||
ret := make([]packet.FieldValue, l)
|
|
||||||
ret = append(ret, pack.Values[:e]...)
|
|
||||||
ret = append(ret, pack.Values[e+1:]...)
|
|
||||||
pack.Values = ret
|
|
||||||
}
|
|
||||||
|
|
||||||
func RemoveLayer(pack *packet.Structure, e int) {
|
|
||||||
l := len(pack.Layers) - 1
|
|
||||||
ret := make([]packet.Layer, l)
|
|
||||||
ret = append(ret, pack.Layers[:e]...)
|
|
||||||
ret = append(ret, pack.Layers[e+1:]...)
|
|
||||||
pack.Layers = ret
|
|
||||||
}
|
|
||||||
|
|
||||||
func Load(pack *packet.Structure, path string) error {
|
|
||||||
data, err := os.ReadFile(path)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = json.Unmarshal(data, pack)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func ToJson(pack *packet.Structure) string {
|
|
||||||
data, err := json.MarshalIndent(*pack, "", " ")
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return string(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Save(pack *packet.Structure, path string) error {
|
|
||||||
data, err := json.MarshalIndent(*pack, "", " ")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = os.WriteFile(path, data, fs.ModeAppend)
|
|
||||||
return err
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
package protocol
|
|
||||||
|
|
||||||
const DOPVersion string = "1.0"
|
|
||||||
|
|
||||||
type DOPMeta struct {
|
|
||||||
// DOP metadata version 1.0
|
|
||||||
DOPVersion string
|
|
||||||
Name string
|
|
||||||
Version string
|
|
||||||
TCPIPLayer uint
|
|
||||||
OSILayer uint
|
|
||||||
ExtensionTo string
|
|
||||||
Description string
|
|
||||||
RequiredJSFunctions []string
|
|
||||||
LowerLayerIdentification map[string]string
|
|
||||||
}
|
|
|
@ -3,13 +3,14 @@ package protocol
|
||||||
import "encoding/json"
|
import "encoding/json"
|
||||||
|
|
||||||
type Field struct {
|
type Field struct {
|
||||||
Name string // Name of the Field
|
Name string // Name of the Field
|
||||||
Desc string // Lengthy description
|
Desc string // Lengthy description
|
||||||
Regex string // Regex to recognize values
|
Regex string // Regex to recognize values
|
||||||
Size int // Size in bits!
|
Size int // Size in bits!
|
||||||
SubFields []Field // Possible sub-fields
|
SubFields []Field // Possible sub-fields
|
||||||
Optional bool // Is this field required?
|
Optional bool // Is this field required?
|
||||||
Payload bool // Is this field the payload or next protocol level?
|
Payload bool // Is this field the payload or next protocol level?
|
||||||
|
JavaScript string
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProtocolFieldReferencer interface {
|
type ProtocolFieldReferencer interface {
|
||||||
|
@ -24,3 +25,29 @@ func (f *Field) ToJson() string {
|
||||||
}
|
}
|
||||||
return string(b)
|
return string(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewEmptyField() *Field {
|
||||||
|
f := Field{}
|
||||||
|
return &f
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewField(
|
||||||
|
name string,
|
||||||
|
desc string,
|
||||||
|
regex string,
|
||||||
|
size int,
|
||||||
|
subfields []Field,
|
||||||
|
optional bool,
|
||||||
|
payload bool,
|
||||||
|
) *Field {
|
||||||
|
f := Field{
|
||||||
|
Name: name,
|
||||||
|
Desc: desc,
|
||||||
|
Regex: regex,
|
||||||
|
Size: size,
|
||||||
|
SubFields: subfields,
|
||||||
|
Optional: optional,
|
||||||
|
Payload: payload,
|
||||||
|
}
|
||||||
|
return &f
|
||||||
|
}
|
||||||
|
|
|
@ -1,13 +1,107 @@
|
||||||
package protocol
|
package protocol
|
||||||
|
|
||||||
type ProtocolStructure struct {
|
import (
|
||||||
Metadata DOPMeta
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Protocol struct {
|
||||||
|
Metadata ProtocolMeta
|
||||||
Structure []*Field
|
Structure []*Field
|
||||||
DefaultValues []DefaultValue
|
DefaultValues []DefaultValue
|
||||||
JavaScript string
|
JavaScript string
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProtocolReferencer interface {
|
func (p Protocol) ToJson() string {
|
||||||
GetProtocol() *ProtocolStructure
|
data, err := json.MarshalIndent(p, "", " ")
|
||||||
SetProtocol(prot *ProtocolStructure)
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return string(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewProtocolStructure() *Protocol {
|
||||||
|
p := Protocol{}
|
||||||
|
return &p
|
||||||
|
}
|
||||||
|
func (prot *Protocol) AppendField(field Field) int {
|
||||||
|
i := len(prot.Structure)
|
||||||
|
prot.Structure = append(prot.Structure, &field)
|
||||||
|
return i + 1
|
||||||
|
}
|
||||||
|
func (prot *Protocol) AddField(index int, field *Field) {
|
||||||
|
if len(prot.Structure) == index {
|
||||||
|
prot.AppendField(*field)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret := make([]*Field, 0)
|
||||||
|
ret = append(ret, prot.Structure[:index]...)
|
||||||
|
ret = append(ret, field)
|
||||||
|
ret = append(ret, prot.Structure[index:]...)
|
||||||
|
prot.Structure = ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (prot *Protocol) UpdateFieldByName(name string, field *Field) {
|
||||||
|
var fnd int = -1
|
||||||
|
for i, f := range prot.Structure {
|
||||||
|
if f.Name == name {
|
||||||
|
fnd = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if fnd != -1 {
|
||||||
|
prot.Structure[fnd] = field
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (prot *Protocol) UpdateFieldByElement(element int, field *Field) {
|
||||||
|
prot.Structure[element] = field
|
||||||
|
}
|
||||||
|
|
||||||
|
func (prot *Protocol) RemoveFieldByName(name string) {
|
||||||
|
element := -1
|
||||||
|
for i, f := range prot.Structure {
|
||||||
|
if f.Name == name {
|
||||||
|
element = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if element == -1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
prot.RemoveFieldByElement(element)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (prot *Protocol) RemoveFieldByElement(field int) {
|
||||||
|
ret := make([]*Field, 0)
|
||||||
|
for i, f := range prot.Structure {
|
||||||
|
if i != field {
|
||||||
|
fmt.Printf("appending %d, %s\n", i, f.ToJson())
|
||||||
|
ret = append(ret, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prot.Structure = ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (prot *Protocol) Load(path string) error {
|
||||||
|
data, err := os.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(data, prot)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
func (prot *Protocol) Save(path string) error {
|
||||||
|
data, err := json.MarshalIndent(*prot, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = os.WriteFile(path, data, fs.ModeAppend)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadNew(path string) (*Protocol, error) {
|
||||||
|
prot := NewProtocolStructure()
|
||||||
|
err := prot.Load(path)
|
||||||
|
return prot, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
package protocolctl
|
package protocol
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"gitea.mmo.to/ppForge/ppforge/protocol"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestUpdateMetaData(t *testing.T) {
|
func TestUpdateMetaData(t *testing.T) {
|
||||||
|
@ -30,7 +28,6 @@ func TestUpdateMetaData(t *testing.T) {
|
||||||
if prot.Metadata.Name != name ||
|
if prot.Metadata.Name != name ||
|
||||||
prot.Metadata.Description != desc ||
|
prot.Metadata.Description != desc ||
|
||||||
prot.Metadata.ExtensionTo != extensionTo ||
|
prot.Metadata.ExtensionTo != extensionTo ||
|
||||||
prot.Metadata.OSILayer != osilayer ||
|
|
||||||
prot.Metadata.TCPIPLayer != tcpiplayer ||
|
prot.Metadata.TCPIPLayer != tcpiplayer ||
|
||||||
prot.Metadata.Version != version ||
|
prot.Metadata.Version != version ||
|
||||||
prot.Metadata.LowerLayerIdentification != nil ||
|
prot.Metadata.LowerLayerIdentification != nil ||
|
||||||
|
@ -40,8 +37,8 @@ func TestUpdateMetaData(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenerateFields() []protocol.Field {
|
func GenerateFields() []Field {
|
||||||
slc := make([]protocol.Field, 0)
|
slc := make([]Field, 0)
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
field := NewField(
|
field := NewField(
|
||||||
fmt.Sprintf("testfield%d", i),
|
fmt.Sprintf("testfield%d", i),
|
||||||
|
@ -57,11 +54,11 @@ func GenerateFields() []protocol.Field {
|
||||||
return slc
|
return slc
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenerateStructure() *protocol.ProtocolStructure {
|
func GenerateStructure() *Protocol {
|
||||||
p := NewProtocolStructure()
|
p := NewProtocolStructure()
|
||||||
slc := GenerateFields()
|
slc := GenerateFields()
|
||||||
for i, e := range slc {
|
for i, e := range slc {
|
||||||
AppendField(p, e)
|
p.AppendField(e)
|
||||||
fmt.Printf("%d %s\n", i, e.ToJson())
|
fmt.Printf("%d %s\n", i, e.ToJson())
|
||||||
}
|
}
|
||||||
for i, e := range p.Structure {
|
for i, e := range p.Structure {
|
||||||
|
@ -82,7 +79,7 @@ func TestFieldAppend(t *testing.T) {
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
p := NewProtocolStructure()
|
p := NewProtocolStructure()
|
||||||
AppendField(p, *f)
|
p.AppendField(*f)
|
||||||
if p.Structure[0].Name != "testfield" {
|
if p.Structure[0].Name != "testfield" {
|
||||||
t.Log("Append failed.")
|
t.Log("Append failed.")
|
||||||
t.Fail()
|
t.Fail()
|
||||||
|
@ -110,7 +107,7 @@ func TestUpdateFieldByElement(t *testing.T) {
|
||||||
f := NewField(
|
f := NewField(
|
||||||
"UpdatedField", "", "", 42, nil, false, true,
|
"UpdatedField", "", "", 42, nil, false, true,
|
||||||
)
|
)
|
||||||
UpdateFieldByElement(p, 5, f)
|
p.UpdateFieldByElement(5, f)
|
||||||
for i, e := range p.Structure {
|
for i, e := range p.Structure {
|
||||||
fmt.Printf("%d %s\n", i, e.ToJson())
|
fmt.Printf("%d %s\n", i, e.ToJson())
|
||||||
}
|
}
|
||||||
|
@ -135,7 +132,7 @@ func TestUpdateFieldByElement(t *testing.T) {
|
||||||
*/
|
*/
|
||||||
func TestRemoveFieldByElement(t *testing.T) {
|
func TestRemoveFieldByElement(t *testing.T) {
|
||||||
p := GenerateStructure()
|
p := GenerateStructure()
|
||||||
RemoveFieldByElement(p, 3)
|
p.RemoveFieldByElement(3)
|
||||||
for i, e := range p.Structure {
|
for i, e := range p.Structure {
|
||||||
fmt.Printf("%d %s\n", i, e.ToJson())
|
fmt.Printf("%d %s\n", i, e.ToJson())
|
||||||
}
|
}
|
||||||
|
@ -147,5 +144,5 @@ func TestRemoveFieldByElement(t *testing.T) {
|
||||||
|
|
||||||
func TestToJson(t *testing.T) {
|
func TestToJson(t *testing.T) {
|
||||||
p := GenerateStructure()
|
p := GenerateStructure()
|
||||||
fmt.Print(ToJson(p))
|
fmt.Print(p.ToJson())
|
||||||
}
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package protocol
|
||||||
|
|
||||||
|
type ProtocolMeta struct {
|
||||||
|
Name string
|
||||||
|
Revision uint
|
||||||
|
Version string
|
||||||
|
TCPIPLayer uint
|
||||||
|
ExtensionTo string
|
||||||
|
Description string
|
||||||
|
RequiredJSFunctions []string
|
||||||
|
LowerLayerIdentification map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateMetaData(
|
||||||
|
prot *Protocol,
|
||||||
|
name string,
|
||||||
|
version string,
|
||||||
|
tcpiplayer uint,
|
||||||
|
osilayer uint,
|
||||||
|
extensionTo string,
|
||||||
|
desc string,
|
||||||
|
) {
|
||||||
|
prot.Metadata.Name = name
|
||||||
|
prot.Metadata.Description = desc
|
||||||
|
prot.Metadata.ExtensionTo = extensionTo
|
||||||
|
prot.Metadata.Version = version
|
||||||
|
prot.Metadata.TCPIPLayer = tcpiplayer
|
||||||
|
}
|
|
@ -1,147 +0,0 @@
|
||||||
package protocolctl
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/fs"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"gitea.mmo.to/ppForge/ppforge/protocol"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewProtocolStructure() *protocol.ProtocolStructure {
|
|
||||||
p := protocol.ProtocolStructure{}
|
|
||||||
return &p
|
|
||||||
}
|
|
||||||
|
|
||||||
func UpdateMetaData(
|
|
||||||
prot *protocol.ProtocolStructure,
|
|
||||||
name string,
|
|
||||||
version string,
|
|
||||||
tcpiplayer uint,
|
|
||||||
osilayer uint,
|
|
||||||
extensionTo string,
|
|
||||||
desc string,
|
|
||||||
) {
|
|
||||||
prot.Metadata.Name = name
|
|
||||||
prot.Metadata.Description = desc
|
|
||||||
prot.Metadata.ExtensionTo = extensionTo
|
|
||||||
prot.Metadata.Version = version
|
|
||||||
prot.Metadata.OSILayer = osilayer
|
|
||||||
prot.Metadata.TCPIPLayer = tcpiplayer
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewEmptyField() *protocol.Field {
|
|
||||||
f := protocol.Field{}
|
|
||||||
return &f
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewField(
|
|
||||||
name string,
|
|
||||||
desc string,
|
|
||||||
regex string,
|
|
||||||
size int,
|
|
||||||
subfields []protocol.Field,
|
|
||||||
optional bool,
|
|
||||||
payload bool,
|
|
||||||
) *protocol.Field {
|
|
||||||
f := protocol.Field{
|
|
||||||
Name: name,
|
|
||||||
Desc: desc,
|
|
||||||
Regex: regex,
|
|
||||||
Size: size,
|
|
||||||
SubFields: subfields,
|
|
||||||
Optional: optional,
|
|
||||||
Payload: payload,
|
|
||||||
}
|
|
||||||
return &f
|
|
||||||
}
|
|
||||||
|
|
||||||
func AppendField(prot *protocol.ProtocolStructure, field protocol.Field) int {
|
|
||||||
i := len(prot.Structure)
|
|
||||||
prot.Structure = append(prot.Structure, &field)
|
|
||||||
return i + 1
|
|
||||||
}
|
|
||||||
func AddField(prot *protocol.ProtocolStructure, index int, field *protocol.Field) {
|
|
||||||
if len(prot.Structure) == index {
|
|
||||||
AppendField(prot, *field)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ret := make([]*protocol.Field, 0)
|
|
||||||
ret = append(ret, prot.Structure[:index]...)
|
|
||||||
ret = append(ret, field)
|
|
||||||
ret = append(ret, prot.Structure[index:]...)
|
|
||||||
prot.Structure = ret
|
|
||||||
}
|
|
||||||
|
|
||||||
func UpdateFieldByName(prot *protocol.ProtocolStructure, name string, field *protocol.Field) {
|
|
||||||
var fnd int = -1
|
|
||||||
for i, f := range prot.Structure {
|
|
||||||
if f.Name == name {
|
|
||||||
fnd = i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if fnd != -1 {
|
|
||||||
prot.Structure[fnd] = field
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func UpdateFieldByElement(prot *protocol.ProtocolStructure, element int, field *protocol.Field) {
|
|
||||||
prot.Structure[element] = field
|
|
||||||
}
|
|
||||||
|
|
||||||
func RemoveFieldByName(prot *protocol.ProtocolStructure, name string) {
|
|
||||||
element := -1
|
|
||||||
for i, f := range prot.Structure {
|
|
||||||
if f.Name == name {
|
|
||||||
element = i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if element == -1 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
RemoveFieldByElement(prot, element)
|
|
||||||
}
|
|
||||||
|
|
||||||
func RemoveFieldByElement(prot *protocol.ProtocolStructure, field int) {
|
|
||||||
ret := make([]*protocol.Field, 0)
|
|
||||||
for i, f := range prot.Structure {
|
|
||||||
if i != field {
|
|
||||||
fmt.Printf("appending %d, %s\n", i, f.ToJson())
|
|
||||||
ret = append(ret, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
prot.Structure = ret
|
|
||||||
}
|
|
||||||
|
|
||||||
func Load(prot *protocol.ProtocolStructure, path string) error {
|
|
||||||
data, err := os.ReadFile(path)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = json.Unmarshal(data, prot)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func LoadNew(path string) (*protocol.ProtocolStructure, error) {
|
|
||||||
prot := NewProtocolStructure()
|
|
||||||
err := Load(prot, path)
|
|
||||||
return prot, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func ToJson(prot *protocol.ProtocolStructure) string {
|
|
||||||
data, err := json.MarshalIndent(*prot, "", " ")
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return string(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Save(prot *protocol.ProtocolStructure, path string) error {
|
|
||||||
data, err := json.MarshalIndent(*prot, "", " ")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = os.WriteFile(path, data, fs.ModeAppend)
|
|
||||||
return err
|
|
||||||
}
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
{
|
||||||
|
"Metadata": {
|
||||||
|
"Revision": 2,
|
||||||
|
"Name": "blabla",
|
||||||
|
"Version": "",
|
||||||
|
"TCPIPLayer": 0,
|
||||||
|
"ExtensionTo": "",
|
||||||
|
"Description": "",
|
||||||
|
"RequiredJSFunctions": null,
|
||||||
|
"LowerLayerIdentification": null
|
||||||
|
},
|
||||||
|
"Structure": [
|
||||||
|
{
|
||||||
|
"Name": "asdfasdf",
|
||||||
|
"Desc": "",
|
||||||
|
"Regex": "",
|
||||||
|
"Size": 8,
|
||||||
|
"SubFields": null,
|
||||||
|
"Optional": false,
|
||||||
|
"Payload": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "asdfasdfasdf",
|
||||||
|
"Desc": "test",
|
||||||
|
"Regex": "",
|
||||||
|
"Size": 24,
|
||||||
|
"SubFields": null,
|
||||||
|
"Optional": false,
|
||||||
|
"Payload": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"DefaultValues": null,
|
||||||
|
"JavaScript": ""
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
{
|
||||||
|
"Metadata": {
|
||||||
|
"Revision": 1,
|
||||||
|
"Name": "blah",
|
||||||
|
"Version": "",
|
||||||
|
"TCPIPLayer": 0,
|
||||||
|
"ExtensionTo": "",
|
||||||
|
"Description": "",
|
||||||
|
"RequiredJSFunctions": null,
|
||||||
|
"LowerLayerIdentification": null
|
||||||
|
},
|
||||||
|
"Structure": [
|
||||||
|
{
|
||||||
|
"Name": "test",
|
||||||
|
"Desc": "",
|
||||||
|
"Regex": "",
|
||||||
|
"Size": 32,
|
||||||
|
"SubFields": null,
|
||||||
|
"Optional": false,
|
||||||
|
"Payload": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "",
|
||||||
|
"Desc": "",
|
||||||
|
"Regex": "",
|
||||||
|
"Size": 32,
|
||||||
|
"SubFields": null,
|
||||||
|
"Optional": false,
|
||||||
|
"Payload": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "",
|
||||||
|
"Desc": "",
|
||||||
|
"Regex": "",
|
||||||
|
"Size": 8,
|
||||||
|
"SubFields": null,
|
||||||
|
"Optional": false,
|
||||||
|
"Payload": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "",
|
||||||
|
"Desc": "",
|
||||||
|
"Regex": "",
|
||||||
|
"Size": 4,
|
||||||
|
"SubFields": null,
|
||||||
|
"Optional": false,
|
||||||
|
"Payload": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "",
|
||||||
|
"Desc": "",
|
||||||
|
"Regex": "",
|
||||||
|
"Size": 20,
|
||||||
|
"SubFields": null,
|
||||||
|
"Optional": false,
|
||||||
|
"Payload": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"DefaultValues": null,
|
||||||
|
"JavaScript": ""
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"Metadata": {
|
||||||
|
"Revision": 1,
|
||||||
|
"Name": "test",
|
||||||
|
"Version": "",
|
||||||
|
"TCPIPLayer": 0,
|
||||||
|
"ExtensionTo": "",
|
||||||
|
"Description": "test",
|
||||||
|
"RequiredJSFunctions": null,
|
||||||
|
"LowerLayerIdentification": null
|
||||||
|
},
|
||||||
|
"Structure": [
|
||||||
|
{
|
||||||
|
"Name": "test",
|
||||||
|
"Desc": "test",
|
||||||
|
"Regex": "",
|
||||||
|
"Size": 128,
|
||||||
|
"SubFields": null,
|
||||||
|
"Optional": false,
|
||||||
|
"Payload": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"DefaultValues": null,
|
||||||
|
"JavaScript": ""
|
||||||
|
}
|
Loading…
Reference in New Issue