1
2
3
4
5
6
7
8
9
10
11
12
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
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 }
144
View as plain text