Skip to content

Commit

Permalink
Add messagetype, vendor name registries and lookups
Browse files Browse the repository at this point in the history
  • Loading branch information
cmikk committed Jun 8, 2023
1 parent 435c054 commit 48d2532
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 4 deletions.
10 changes: 10 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
module github.com/farsightsec/go-nmsg

go 1.18

require (
github.com/dnstap/golang-dnstap v0.4.0
google.golang.org/protobuf v1.25.0
gopkg.in/yaml.v2 v2.4.0
)

require (
github.com/farsightsec/golang-framestream v0.3.0 // indirect
github.com/miekg/dns v1.1.31 // indirect
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 // indirect
golang.org/x/net v0.0.0-20190923162816-aa69164e4478 // indirect
golang.org/x/sys v0.8.0 // indirect
)
3 changes: 2 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe h1:6fAMxZRR6sl1Uq8U61gxU+kPTs2tR8uOySCbBP7BN/M=
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.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-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
Expand Down
1 change: 1 addition & 0 deletions nmsg_base/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func (d *DnsObs) GetVid() uint32 { return 1 }
func (d *DnsObs) GetMsgtype() uint32 { return 14 }

func init() {
nmsg.RegisterVendor("base", 1)
nmsg.Register(&Ncap{})
nmsg.Register(&Email{})
nmsg.Register(&Linkpair{})
Expand Down
102 changes: 99 additions & 3 deletions register.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,14 @@ package nmsg
import (
"fmt"
"reflect"
"strings"
)

var types map[uint32]map[uint32]reflect.Type
var typesByName map[uint32]map[string]uint32

var vendors map[uint32]string
var vids map[string]uint32

// Register records the supplied message's type, indexed by its MessageType
// and VendorID, for the purposes of decoding protobuf-encoded payloads.
Expand All @@ -24,6 +29,7 @@ var types map[uint32]map[uint32]reflect.Type
func Register(m Message) {
if types == nil {
types = make(map[uint32]map[uint32]reflect.Type)
typesByName = make(map[uint32]map[string]uint32)
}
vid := m.GetVid()
v, ok := types[vid]
Expand All @@ -34,12 +40,39 @@ func Register(m Message) {

msgtype := m.GetMsgtype()
v[msgtype] = reflect.TypeOf(m)

name := strings.ToLower(v[msgtype].Elem().Name())

tn, ok := typesByName[vid]
if !ok {
tn = make(map[string]uint32)
typesByName[vid] = tn
}

tn[name] = msgtype
}

// RegisterVendor records an association between the vendor named `vname`
// and a numeric vendor id `vid`
func RegisterVendor(vname string, vid uint32) {
if vendors == nil {
vendors = make(map[uint32]string)
vids = make(map[string]uint32)
}
vendors[vid] = vname
vids[vname] = vid
}

type unknownVid uint32

func (v unknownVid) Error() string {
return fmt.Sprintf("Vendor %d not registered.", v)
}

type unknownVendor uint32
type unknownVendor string

func (v unknownVendor) Error() string {
return fmt.Sprintf("Vendor %d has no registered Msgtypes.", v)
return fmt.Sprintf("Vendor '%s' not registered.", string(v))
}

type unknownMsgtype struct{ vid, msgtype uint32 }
Expand All @@ -53,7 +86,7 @@ func (t unknownMsgtype) Error() string {
func NewMessage(vid, msgtype uint32) (Message, error) {
v, ok := types[vid]
if !ok {
return nil, unknownVendor(vid)
return nil, unknownVid(vid)
}

t, ok := v[msgtype]
Expand All @@ -63,3 +96,66 @@ func NewMessage(vid, msgtype uint32) (Message, error) {

return reflect.New(t.Elem()).Interface().(Message), nil
}

// VendorByname returns the numeric vendor id registered for the given
// name, if any.
func VendorByName(vname string) (uint32, error) {
vid, ok := vids[vname]
if !ok {
return 0, unknownVendor(vname)
}
return vid, nil
}

// VendorName returns the vendor name registered for the given
// numeric vid, if any.
func VendorName(vid uint32) (string, error) {
vname, ok := vendors[vid]
if !ok {
return "", unknownVid(vid)
}
return vname, nil
}

// MessageTypeByName returns the numeric vendor id and message type
// for the given vendor name and message type name, for the purposes
// of creating a new message with NewMessage().
func MessageTypeByName(vname string, mname string) (vid uint32, mtype uint32, err error) {
var ok bool

vid, err = VendorByName(vname)
if err != nil {
return
}

mtype, ok = typesByName[vid][strings.ToLower(mname)]
if !ok {
err = fmt.Errorf("Unknown message type '%s' for vendor '%s'", mname, vname)
}
return
}

// MessageTypeName returns a vendor and message type name for a given
// numeric vendor id and message type, if any
func MessageTypeName(vid uint32, msgtype uint32) (vname string, mname string, err error) {
var ok bool
vname, err = VendorName(vid)
if err != nil {
return
}

v, ok := types[vid]
if !ok {
err = unknownVid(vid)
return
}

t, ok := v[msgtype]
if !ok {
err = unknownMsgtype{vid, msgtype}
return
}

mname = strings.ToLower(t.Elem().Name())
return
}
33 changes: 33 additions & 0 deletions register_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package nmsg_test

import (
"github.com/farsightsec/go-nmsg"
_ "github.com/farsightsec/go-nmsg/nmsg_base"
"testing"
)

func TestRegisterVendor(t *testing.T) {
vname, err := nmsg.VendorName(1)
if err != nil || vname != "base" {
t.Errorf("VendorName(1): %s, %v", vname, err)
}

vid, err := nmsg.VendorByName("base")
if err != nil || vid != 1 {
t.Errorf("VendorByName(base): %d, %v", vid, err)
}
}

func TestRegisterMessageByName(t *testing.T) {
vid, msgtype, err := nmsg.MessageTypeByName("base", "ncap")
if err != nil || vid != 1 || msgtype != 1 {
t.Errorf("MessageTypeByName(base,ncap): %d, %d, %v", vid, msgtype, err)
}
}

func TestRegisterMessageName(t *testing.T) {
vname, mname, err := nmsg.MessageTypeName(1, 1)
if err != nil || vname != "base" || mname != "ncap" {
t.Errorf("MessageTypeByName(base,ncap): %s, %s, %v", vname, mname, err)
}
}

0 comments on commit 48d2532

Please sign in to comment.