...
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 "strings"
22
23 "github.com/prometheus/procfs/internal/util"
24 )
25
26
27
28 type ConntrackStatEntry struct {
29 Entries uint64
30 Searched uint64
31 Found uint64
32 New uint64
33 Invalid uint64
34 Ignore uint64
35 Delete uint64
36 DeleteList uint64
37 Insert uint64
38 InsertFailed uint64
39 Drop uint64
40 EarlyDrop uint64
41 SearchRestart uint64
42 }
43
44
45 func (fs FS) ConntrackStat() ([]ConntrackStatEntry, error) {
46 return readConntrackStat(fs.proc.Path("net", "stat", "nf_conntrack"))
47 }
48
49
50 func readConntrackStat(path string) ([]ConntrackStatEntry, error) {
51
52 b, err := util.ReadFileNoStat(path)
53 if err != nil {
54
55
56 return nil, err
57 }
58
59 stat, err := parseConntrackStat(bytes.NewReader(b))
60 if err != nil {
61 return nil, fmt.Errorf("%s: Cannot read file: %v: %w", ErrFileRead, path, err)
62 }
63
64 return stat, nil
65 }
66
67
68 func parseConntrackStat(r io.Reader) ([]ConntrackStatEntry, error) {
69 var entries []ConntrackStatEntry
70
71 scanner := bufio.NewScanner(r)
72 scanner.Scan()
73 for scanner.Scan() {
74 fields := strings.Fields(scanner.Text())
75 conntrackEntry, err := parseConntrackStatEntry(fields)
76 if err != nil {
77 return nil, err
78 }
79 entries = append(entries, *conntrackEntry)
80 }
81
82 return entries, nil
83 }
84
85
86 func parseConntrackStatEntry(fields []string) (*ConntrackStatEntry, error) {
87 entries, err := util.ParseHexUint64s(fields)
88 if err != nil {
89 return nil, fmt.Errorf("%s: Cannot parse entry: %d: %w", ErrFileParse, entries, err)
90 }
91 numEntries := len(entries)
92 if numEntries < 16 || numEntries > 17 {
93 return nil,
94 fmt.Errorf("%w: invalid conntrackstat entry, invalid number of fields: %d", ErrFileParse, numEntries)
95 }
96
97 stats := &ConntrackStatEntry{
98 Entries: *entries[0],
99 Searched: *entries[1],
100 Found: *entries[2],
101 New: *entries[3],
102 Invalid: *entries[4],
103 Ignore: *entries[5],
104 Delete: *entries[6],
105 DeleteList: *entries[7],
106 Insert: *entries[8],
107 InsertFailed: *entries[9],
108 Drop: *entries[10],
109 EarlyDrop: *entries[11],
110 }
111
112
113 if numEntries == 17 {
114 stats.SearchRestart = *entries[16]
115 }
116
117 return stats, nil
118 }
119
View as plain text