Skip to content

Commit 1d6add5

Browse files
sansnaSuperQ
andauthored
Add net/route parse, also add util lib Pars… (prometheus#508)
* @wentao[add-net-route]: added net/route parse, also add util lib ParseIpv4FromHexString function - sansna --------- Signed-off-by: sansna <[email protected]> Signed-off-by: 三叁 <[email protected]> Co-authored-by: Ben Kochie <[email protected]>
1 parent abbfda0 commit 1d6add5

File tree

2 files changed

+203
-0
lines changed

2 files changed

+203
-0
lines changed

net_route.go

+143
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
// Copyright 2023 The Prometheus Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
package procfs
15+
16+
import (
17+
"bufio"
18+
"bytes"
19+
"fmt"
20+
"io"
21+
"strconv"
22+
"strings"
23+
24+
"github.com/prometheus/procfs/internal/util"
25+
)
26+
27+
const (
28+
blackholeRepresentation string = "*"
29+
blackholeIfaceName string = "blackhole"
30+
routeLineColumns int = 11
31+
)
32+
33+
// A NetRouteLine represents one line from net/route.
34+
type NetRouteLine struct {
35+
Iface string
36+
Destination uint32
37+
Gateway uint32
38+
Flags uint32
39+
RefCnt uint32
40+
Use uint32
41+
Metric uint32
42+
Mask uint32
43+
MTU uint32
44+
Window uint32
45+
IRTT uint32
46+
}
47+
48+
func (fs FS) NetRoute() ([]NetRouteLine, error) {
49+
return readNetRoute(fs.proc.Path("net", "route"))
50+
}
51+
52+
func readNetRoute(path string) ([]NetRouteLine, error) {
53+
b, err := util.ReadFileNoStat(path)
54+
if err != nil {
55+
return nil, err
56+
}
57+
58+
routelines, err := parseNetRoute(bytes.NewReader(b))
59+
if err != nil {
60+
return nil, fmt.Errorf("failed to read net route from %s: %w", path, err)
61+
}
62+
return routelines, nil
63+
}
64+
65+
func parseNetRoute(r io.Reader) ([]NetRouteLine, error) {
66+
var routelines []NetRouteLine
67+
68+
scanner := bufio.NewScanner(r)
69+
scanner.Scan()
70+
for scanner.Scan() {
71+
fields := strings.Fields(scanner.Text())
72+
routeline, err := parseNetRouteLine(fields)
73+
if err != nil {
74+
return nil, err
75+
}
76+
routelines = append(routelines, *routeline)
77+
}
78+
return routelines, nil
79+
}
80+
81+
func parseNetRouteLine(fields []string) (*NetRouteLine, error) {
82+
if len(fields) != routeLineColumns {
83+
return nil, fmt.Errorf("invalid routeline, num of digits: %d", len(fields))
84+
}
85+
iface := fields[0]
86+
if iface == blackholeRepresentation {
87+
iface = blackholeIfaceName
88+
}
89+
destination, err := strconv.ParseUint(fields[1], 16, 32)
90+
if err != nil {
91+
return nil, err
92+
}
93+
gateway, err := strconv.ParseUint(fields[2], 16, 32)
94+
if err != nil {
95+
return nil, err
96+
}
97+
flags, err := strconv.ParseUint(fields[3], 10, 32)
98+
if err != nil {
99+
return nil, err
100+
}
101+
refcnt, err := strconv.ParseUint(fields[4], 10, 32)
102+
if err != nil {
103+
return nil, err
104+
}
105+
use, err := strconv.ParseUint(fields[5], 10, 32)
106+
if err != nil {
107+
return nil, err
108+
}
109+
metric, err := strconv.ParseUint(fields[6], 10, 32)
110+
if err != nil {
111+
return nil, err
112+
}
113+
mask, err := strconv.ParseUint(fields[7], 16, 32)
114+
if err != nil {
115+
return nil, err
116+
}
117+
mtu, err := strconv.ParseUint(fields[8], 10, 32)
118+
if err != nil {
119+
return nil, err
120+
}
121+
window, err := strconv.ParseUint(fields[9], 10, 32)
122+
if err != nil {
123+
return nil, err
124+
}
125+
irtt, err := strconv.ParseUint(fields[10], 10, 32)
126+
if err != nil {
127+
return nil, err
128+
}
129+
routeline := &NetRouteLine{
130+
Iface: iface,
131+
Destination: uint32(destination),
132+
Gateway: uint32(gateway),
133+
Flags: uint32(flags),
134+
RefCnt: uint32(refcnt),
135+
Use: uint32(use),
136+
Metric: uint32(metric),
137+
Mask: uint32(mask),
138+
MTU: uint32(mtu),
139+
Window: uint32(window),
140+
IRTT: uint32(irtt),
141+
}
142+
return routeline, nil
143+
}

net_route_test.go

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright 2023 The Prometheus Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
package procfs
15+
16+
import (
17+
"bytes"
18+
"reflect"
19+
"testing"
20+
)
21+
22+
func TestParseNetRoute(t *testing.T) {
23+
var netRoute = []byte(`Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
24+
eno16780032 00000000 9503A8C0 0003 0 0 100 00000000 0 0 0
25+
eno16780032 0000A8C0 00000000 0001 0 0 100 0000FFFF 0 0 0`)
26+
27+
r := bytes.NewReader(netRoute)
28+
parsed, _ := parseNetRoute(r)
29+
want := []NetRouteLine{
30+
{
31+
Iface: "eno16780032",
32+
Destination: 0,
33+
Gateway: 2500044992,
34+
Flags: 3,
35+
RefCnt: 0,
36+
Use: 0,
37+
Metric: 100,
38+
Mask: 0,
39+
MTU: 0,
40+
Window: 0,
41+
IRTT: 0,
42+
},
43+
{
44+
Iface: "eno16780032",
45+
Destination: 43200,
46+
Gateway: 0,
47+
Flags: 1,
48+
RefCnt: 0,
49+
Use: 0,
50+
Metric: 100,
51+
Mask: 65535,
52+
MTU: 0,
53+
Window: 0,
54+
IRTT: 0,
55+
},
56+
}
57+
if !reflect.DeepEqual(want, parsed) {
58+
t.Errorf("want %v, parsed %v", want, parsed)
59+
}
60+
}

0 commit comments

Comments
 (0)