Skip to content

Commit b347cc6

Browse files
committed
feat: parse ros ospf lsa network
1 parent a9f2599 commit b347cc6

File tree

4 files changed

+61
-20
lines changed

4 files changed

+61
-20
lines changed

backend/graph/fetch/ros/ros.go

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,14 @@
11
package ros
22

33
import (
4-
"bytes"
5-
"encoding/gob"
64
"fmt"
75
"github.com/BaiMeow/NetworkMonitor/graph/fetch"
86
"github.com/go-routeros/routeros"
9-
"github.com/go-routeros/routeros/proto"
107
"net"
118
"time"
129
)
1310

1411
func init() {
15-
gob.Register(&proto.Sentence{})
16-
1712
fetch.Register("ros", func(config map[string]any) (fetch.Fetcher, error) {
1813
addr, ok := config["address"].(string)
1914
if !ok {
@@ -57,8 +52,5 @@ func (R *ROS) GetData() (any, error) {
5752
if err != nil {
5853
return nil, err
5954
}
60-
61-
buf := &bytes.Buffer{}
62-
gob.NewEncoder(buf).Encode(reply.Re)
63-
return buf.Bytes(), nil
55+
return reply.Re, nil
6456
}

backend/graph/fetch/ros/ros_test.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package ros
22

33
import (
4+
"bytes"
45
"encoding/base64"
6+
"encoding/gob"
7+
"github.com/go-routeros/routeros/proto"
58
"testing"
69
)
710

@@ -15,7 +18,11 @@ func TestROS_GetData(t *testing.T) {
1518
if err != nil {
1619
t.Fatal(err)
1720
}
18-
t.Log(base64.StdEncoding.EncodeToString(resp.([]byte)))
21+
sentences := resp.([]*proto.Sentence)
22+
gob.Register(sentences)
23+
var buf bytes.Buffer
24+
gob.NewEncoder(&buf).Encode(sentences)
25+
t.Log(base64.StdEncoding.EncodeToString(buf.Bytes()))
1926

2027
ros7 := &ROS{
2128
Address: "10.28.0.1:8728",
@@ -26,5 +33,8 @@ func TestROS_GetData(t *testing.T) {
2633
if err != nil {
2734
t.Fatal(err)
2835
}
29-
t.Log(base64.StdEncoding.EncodeToString(resp.([]byte)))
36+
sentences = resp.([]*proto.Sentence)
37+
gob.Register(sentences)
38+
gob.NewEncoder(&buf).Encode(sentences)
39+
t.Log(base64.StdEncoding.EncodeToString(buf.Bytes()))
3040
}

backend/graph/parse/rosospf/ros_ospf.go

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package rosospf
22

33
import (
4-
"bytes"
54
"encoding/gob"
65
"github.com/BaiMeow/NetworkMonitor/graph/entity"
76
"log"
@@ -22,8 +21,9 @@ func init() {
2221
}
2322

2423
var (
25-
ros6BodyPtpReg = regexp.MustCompile(`Point-To-Point ((?:[0-9]{1,3}\.){3}[0-9]{1,3}) (?:[0-9]{1,3}\.){3}[0-9]{1,3} (\d+)`)
26-
ros7BodyPtpReg = regexp.MustCompile(`type=p2p id=((?:[0-9]{1,3}\.){3}[0-9]{1,3}) data=(?:[0-9]{1,3}\.){3}[0-9]{1,3} metric=(\d+)`)
24+
ros6BodyPtpReg = regexp.MustCompile(`Point-To-Point ((?:[0-9]{1,3}\.){3}[0-9]{1,3}) (?:[0-9]{1,3}\.){3}[0-9]{1,3} (\d+)`)
25+
ros7BodyPtpReg = regexp.MustCompile(`type=p2p id=((?:[0-9]{1,3}\.){3}[0-9]{1,3}) data=(?:[0-9]{1,3}\.){3}[0-9]{1,3} metric=(\d+)`)
26+
ros7BodyNetworkReg = regexp.MustCompile(`type=network id=((?:[0-9]{1,3}\.){3}[0-9]{1,3}) data=(?:[0-9]{1,3}\.){3}[0-9]{1,3} metric=(\d+)`)
2727
)
2828

2929
var _ parse.Parser[*entity.OSPF] = (*RosOSPF)(nil)
@@ -32,17 +32,21 @@ type RosOSPF struct {
3232
parse.Base[*entity.OSPF]
3333
}
3434

35+
type network struct {
36+
cost int
37+
area string
38+
routers []string
39+
}
40+
3541
func (p *RosOSPF) Parse(input any) (*entity.OSPF, error) {
36-
raw, ok := input.([]byte)
42+
sentences, ok := input.([]*proto.Sentence)
3743
if !ok {
3844
log.Fatalf("invalid input data type: %s\n", reflect.TypeOf(input).Elem())
3945
}
4046

41-
var graph entity.OSPF
42-
43-
var sentences []*proto.Sentence
44-
gob.NewDecoder(bytes.NewReader(raw)).Decode(&sentences) // 这里本来应该在初始化就直接处理了,但是因为Init没有抛异常,所以这一步在这里做
47+
networks := make(map[string]*network)
4548

49+
var graph entity.OSPF
4650
for _, sentence := range sentences {
4751
if sentence.Word == "!done" { // 这个判断可有可无 因为fetcher已经做了处理
4852
break
@@ -74,6 +78,36 @@ func (p *RosOSPF) Parse(input any) (*entity.OSPF, error) {
7478
}
7579
graph.AddLink(sentence.Map["area"], sentence.Map["id"], field[1], cost)
7680
}
81+
nw := ros7BodyNetworkReg.FindAllStringSubmatch(sentence.Map["body"], -1)
82+
for _, field := range nw {
83+
if len(field) != 3 {
84+
continue
85+
}
86+
cost, err := strconv.Atoi(field[2])
87+
if err != nil {
88+
continue
89+
}
90+
nw := networks[field[1]]
91+
if nw == nil {
92+
nw = &network{
93+
cost: cost,
94+
area: sentence.Map["area"],
95+
}
96+
networks[field[1]] = nw
97+
}
98+
nw.routers = append(nw.routers, sentence.Map["id"])
99+
}
77100
}
101+
102+
for _, network := range networks {
103+
area := graph.GetArea(network.area)
104+
for i := 0; i < len(network.routers); i++ {
105+
for j := i + 1; j < len(network.routers); j++ {
106+
area.AddLink(network.routers[i], network.routers[j], network.cost)
107+
area.AddLink(network.routers[j], network.routers[i], network.cost)
108+
}
109+
}
110+
}
111+
78112
return &graph, nil
79113
}

backend/graph/parse/rosospf/ros_ospf_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package rosospf
22

33
import (
4+
"bytes"
45
"encoding/base64"
6+
"encoding/gob"
57
"encoding/json"
68
"github.com/BaiMeow/NetworkMonitor/graph/entity"
9+
"github.com/go-routeros/routeros/proto"
710
"testing"
811

912
"github.com/stretchr/testify/assert"
@@ -30,8 +33,10 @@ func TestROSOSPF(t *testing.T) {
3033
for _, v := range testcases {
3134
t.Run(v.name, func(t *testing.T) {
3235
gobOutput, err := base64.StdEncoding.DecodeString(v.feterOutput)
36+
var sentences []*proto.Sentence
37+
gob.NewDecoder(bytes.NewReader(gobOutput)).Decode(&sentences)
3338
p := RosOSPF{}
34-
res, err := p.Parse(gobOutput)
39+
res, err := p.Parse(sentences)
3540
assert.NoError(t, err)
3641
o := &entity.OSPF{}
3742
_ = json.Unmarshal([]byte(v.ospfData), o)

0 commit comments

Comments
 (0)