1 | // Copyright 2022 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 | // ProcNetstat models the content of /proc/<pid>/net/netstat.
|
---|
28 | type ProcNetstat struct {
|
---|
29 | // The process ID.
|
---|
30 | PID int
|
---|
31 | TcpExt
|
---|
32 | IpExt
|
---|
33 | }
|
---|
34 |
|
---|
35 | type TcpExt struct { // nolint:revive
|
---|
36 | SyncookiesSent float64
|
---|
37 | SyncookiesRecv float64
|
---|
38 | SyncookiesFailed float64
|
---|
39 | EmbryonicRsts float64
|
---|
40 | PruneCalled float64
|
---|
41 | RcvPruned float64
|
---|
42 | OfoPruned float64
|
---|
43 | OutOfWindowIcmps float64
|
---|
44 | LockDroppedIcmps float64
|
---|
45 | ArpFilter float64
|
---|
46 | TW float64
|
---|
47 | TWRecycled float64
|
---|
48 | TWKilled float64
|
---|
49 | PAWSActive float64
|
---|
50 | PAWSEstab float64
|
---|
51 | DelayedACKs float64
|
---|
52 | DelayedACKLocked float64
|
---|
53 | DelayedACKLost float64
|
---|
54 | ListenOverflows float64
|
---|
55 | ListenDrops float64
|
---|
56 | TCPHPHits float64
|
---|
57 | TCPPureAcks float64
|
---|
58 | TCPHPAcks float64
|
---|
59 | TCPRenoRecovery float64
|
---|
60 | TCPSackRecovery float64
|
---|
61 | TCPSACKReneging float64
|
---|
62 | TCPSACKReorder float64
|
---|
63 | TCPRenoReorder float64
|
---|
64 | TCPTSReorder float64
|
---|
65 | TCPFullUndo float64
|
---|
66 | TCPPartialUndo float64
|
---|
67 | TCPDSACKUndo float64
|
---|
68 | TCPLossUndo float64
|
---|
69 | TCPLostRetransmit float64
|
---|
70 | TCPRenoFailures float64
|
---|
71 | TCPSackFailures float64
|
---|
72 | TCPLossFailures float64
|
---|
73 | TCPFastRetrans float64
|
---|
74 | TCPSlowStartRetrans float64
|
---|
75 | TCPTimeouts float64
|
---|
76 | TCPLossProbes float64
|
---|
77 | TCPLossProbeRecovery float64
|
---|
78 | TCPRenoRecoveryFail float64
|
---|
79 | TCPSackRecoveryFail float64
|
---|
80 | TCPRcvCollapsed float64
|
---|
81 | TCPDSACKOldSent float64
|
---|
82 | TCPDSACKOfoSent float64
|
---|
83 | TCPDSACKRecv float64
|
---|
84 | TCPDSACKOfoRecv float64
|
---|
85 | TCPAbortOnData float64
|
---|
86 | TCPAbortOnClose float64
|
---|
87 | TCPAbortOnMemory float64
|
---|
88 | TCPAbortOnTimeout float64
|
---|
89 | TCPAbortOnLinger float64
|
---|
90 | TCPAbortFailed float64
|
---|
91 | TCPMemoryPressures float64
|
---|
92 | TCPMemoryPressuresChrono float64
|
---|
93 | TCPSACKDiscard float64
|
---|
94 | TCPDSACKIgnoredOld float64
|
---|
95 | TCPDSACKIgnoredNoUndo float64
|
---|
96 | TCPSpuriousRTOs float64
|
---|
97 | TCPMD5NotFound float64
|
---|
98 | TCPMD5Unexpected float64
|
---|
99 | TCPMD5Failure float64
|
---|
100 | TCPSackShifted float64
|
---|
101 | TCPSackMerged float64
|
---|
102 | TCPSackShiftFallback float64
|
---|
103 | TCPBacklogDrop float64
|
---|
104 | PFMemallocDrop float64
|
---|
105 | TCPMinTTLDrop float64
|
---|
106 | TCPDeferAcceptDrop float64
|
---|
107 | IPReversePathFilter float64
|
---|
108 | TCPTimeWaitOverflow float64
|
---|
109 | TCPReqQFullDoCookies float64
|
---|
110 | TCPReqQFullDrop float64
|
---|
111 | TCPRetransFail float64
|
---|
112 | TCPRcvCoalesce float64
|
---|
113 | TCPOFOQueue float64
|
---|
114 | TCPOFODrop float64
|
---|
115 | TCPOFOMerge float64
|
---|
116 | TCPChallengeACK float64
|
---|
117 | TCPSYNChallenge float64
|
---|
118 | TCPFastOpenActive float64
|
---|
119 | TCPFastOpenActiveFail float64
|
---|
120 | TCPFastOpenPassive float64
|
---|
121 | TCPFastOpenPassiveFail float64
|
---|
122 | TCPFastOpenListenOverflow float64
|
---|
123 | TCPFastOpenCookieReqd float64
|
---|
124 | TCPFastOpenBlackhole float64
|
---|
125 | TCPSpuriousRtxHostQueues float64
|
---|
126 | BusyPollRxPackets float64
|
---|
127 | TCPAutoCorking float64
|
---|
128 | TCPFromZeroWindowAdv float64
|
---|
129 | TCPToZeroWindowAdv float64
|
---|
130 | TCPWantZeroWindowAdv float64
|
---|
131 | TCPSynRetrans float64
|
---|
132 | TCPOrigDataSent float64
|
---|
133 | TCPHystartTrainDetect float64
|
---|
134 | TCPHystartTrainCwnd float64
|
---|
135 | TCPHystartDelayDetect float64
|
---|
136 | TCPHystartDelayCwnd float64
|
---|
137 | TCPACKSkippedSynRecv float64
|
---|
138 | TCPACKSkippedPAWS float64
|
---|
139 | TCPACKSkippedSeq float64
|
---|
140 | TCPACKSkippedFinWait2 float64
|
---|
141 | TCPACKSkippedTimeWait float64
|
---|
142 | TCPACKSkippedChallenge float64
|
---|
143 | TCPWinProbe float64
|
---|
144 | TCPKeepAlive float64
|
---|
145 | TCPMTUPFail float64
|
---|
146 | TCPMTUPSuccess float64
|
---|
147 | TCPWqueueTooBig float64
|
---|
148 | }
|
---|
149 |
|
---|
150 | type IpExt struct { // nolint:revive
|
---|
151 | InNoRoutes float64
|
---|
152 | InTruncatedPkts float64
|
---|
153 | InMcastPkts float64
|
---|
154 | OutMcastPkts float64
|
---|
155 | InBcastPkts float64
|
---|
156 | OutBcastPkts float64
|
---|
157 | InOctets float64
|
---|
158 | OutOctets float64
|
---|
159 | InMcastOctets float64
|
---|
160 | OutMcastOctets float64
|
---|
161 | InBcastOctets float64
|
---|
162 | OutBcastOctets float64
|
---|
163 | InCsumErrors float64
|
---|
164 | InNoECTPkts float64
|
---|
165 | InECT1Pkts float64
|
---|
166 | InECT0Pkts float64
|
---|
167 | InCEPkts float64
|
---|
168 | ReasmOverlaps float64
|
---|
169 | }
|
---|
170 |
|
---|
171 | func (p Proc) Netstat() (ProcNetstat, error) {
|
---|
172 | filename := p.path("net/netstat")
|
---|
173 | data, err := util.ReadFileNoStat(filename)
|
---|
174 | if err != nil {
|
---|
175 | return ProcNetstat{PID: p.PID}, err
|
---|
176 | }
|
---|
177 | procNetstat, err := parseNetstat(bytes.NewReader(data), filename)
|
---|
178 | procNetstat.PID = p.PID
|
---|
179 | return procNetstat, err
|
---|
180 | }
|
---|
181 |
|
---|
182 | // parseNetstat parses the metrics from proc/<pid>/net/netstat file
|
---|
183 | // and returns a ProcNetstat structure.
|
---|
184 | func parseNetstat(r io.Reader, fileName string) (ProcNetstat, error) {
|
---|
185 | var (
|
---|
186 | scanner = bufio.NewScanner(r)
|
---|
187 | procNetstat = ProcNetstat{}
|
---|
188 | )
|
---|
189 |
|
---|
190 | for scanner.Scan() {
|
---|
191 | nameParts := strings.Split(scanner.Text(), " ")
|
---|
192 | scanner.Scan()
|
---|
193 | valueParts := strings.Split(scanner.Text(), " ")
|
---|
194 | // Remove trailing :.
|
---|
195 | protocol := strings.TrimSuffix(nameParts[0], ":")
|
---|
196 | if len(nameParts) != len(valueParts) {
|
---|
197 | return procNetstat, fmt.Errorf("mismatch field count mismatch in %s: %s",
|
---|
198 | fileName, protocol)
|
---|
199 | }
|
---|
200 | for i := 1; i < len(nameParts); i++ {
|
---|
201 | value, err := strconv.ParseFloat(valueParts[i], 64)
|
---|
202 | if err != nil {
|
---|
203 | return procNetstat, err
|
---|
204 | }
|
---|
205 | key := nameParts[i]
|
---|
206 |
|
---|
207 | switch protocol {
|
---|
208 | case "TcpExt":
|
---|
209 | switch key {
|
---|
210 | case "SyncookiesSent":
|
---|
211 | procNetstat.TcpExt.SyncookiesSent = value
|
---|
212 | case "SyncookiesRecv":
|
---|
213 | procNetstat.TcpExt.SyncookiesRecv = value
|
---|
214 | case "SyncookiesFailed":
|
---|
215 | procNetstat.TcpExt.SyncookiesFailed = value
|
---|
216 | case "EmbryonicRsts":
|
---|
217 | procNetstat.TcpExt.EmbryonicRsts = value
|
---|
218 | case "PruneCalled":
|
---|
219 | procNetstat.TcpExt.PruneCalled = value
|
---|
220 | case "RcvPruned":
|
---|
221 | procNetstat.TcpExt.RcvPruned = value
|
---|
222 | case "OfoPruned":
|
---|
223 | procNetstat.TcpExt.OfoPruned = value
|
---|
224 | case "OutOfWindowIcmps":
|
---|
225 | procNetstat.TcpExt.OutOfWindowIcmps = value
|
---|
226 | case "LockDroppedIcmps":
|
---|
227 | procNetstat.TcpExt.LockDroppedIcmps = value
|
---|
228 | case "ArpFilter":
|
---|
229 | procNetstat.TcpExt.ArpFilter = value
|
---|
230 | case "TW":
|
---|
231 | procNetstat.TcpExt.TW = value
|
---|
232 | case "TWRecycled":
|
---|
233 | procNetstat.TcpExt.TWRecycled = value
|
---|
234 | case "TWKilled":
|
---|
235 | procNetstat.TcpExt.TWKilled = value
|
---|
236 | case "PAWSActive":
|
---|
237 | procNetstat.TcpExt.PAWSActive = value
|
---|
238 | case "PAWSEstab":
|
---|
239 | procNetstat.TcpExt.PAWSEstab = value
|
---|
240 | case "DelayedACKs":
|
---|
241 | procNetstat.TcpExt.DelayedACKs = value
|
---|
242 | case "DelayedACKLocked":
|
---|
243 | procNetstat.TcpExt.DelayedACKLocked = value
|
---|
244 | case "DelayedACKLost":
|
---|
245 | procNetstat.TcpExt.DelayedACKLost = value
|
---|
246 | case "ListenOverflows":
|
---|
247 | procNetstat.TcpExt.ListenOverflows = value
|
---|
248 | case "ListenDrops":
|
---|
249 | procNetstat.TcpExt.ListenDrops = value
|
---|
250 | case "TCPHPHits":
|
---|
251 | procNetstat.TcpExt.TCPHPHits = value
|
---|
252 | case "TCPPureAcks":
|
---|
253 | procNetstat.TcpExt.TCPPureAcks = value
|
---|
254 | case "TCPHPAcks":
|
---|
255 | procNetstat.TcpExt.TCPHPAcks = value
|
---|
256 | case "TCPRenoRecovery":
|
---|
257 | procNetstat.TcpExt.TCPRenoRecovery = value
|
---|
258 | case "TCPSackRecovery":
|
---|
259 | procNetstat.TcpExt.TCPSackRecovery = value
|
---|
260 | case "TCPSACKReneging":
|
---|
261 | procNetstat.TcpExt.TCPSACKReneging = value
|
---|
262 | case "TCPSACKReorder":
|
---|
263 | procNetstat.TcpExt.TCPSACKReorder = value
|
---|
264 | case "TCPRenoReorder":
|
---|
265 | procNetstat.TcpExt.TCPRenoReorder = value
|
---|
266 | case "TCPTSReorder":
|
---|
267 | procNetstat.TcpExt.TCPTSReorder = value
|
---|
268 | case "TCPFullUndo":
|
---|
269 | procNetstat.TcpExt.TCPFullUndo = value
|
---|
270 | case "TCPPartialUndo":
|
---|
271 | procNetstat.TcpExt.TCPPartialUndo = value
|
---|
272 | case "TCPDSACKUndo":
|
---|
273 | procNetstat.TcpExt.TCPDSACKUndo = value
|
---|
274 | case "TCPLossUndo":
|
---|
275 | procNetstat.TcpExt.TCPLossUndo = value
|
---|
276 | case "TCPLostRetransmit":
|
---|
277 | procNetstat.TcpExt.TCPLostRetransmit = value
|
---|
278 | case "TCPRenoFailures":
|
---|
279 | procNetstat.TcpExt.TCPRenoFailures = value
|
---|
280 | case "TCPSackFailures":
|
---|
281 | procNetstat.TcpExt.TCPSackFailures = value
|
---|
282 | case "TCPLossFailures":
|
---|
283 | procNetstat.TcpExt.TCPLossFailures = value
|
---|
284 | case "TCPFastRetrans":
|
---|
285 | procNetstat.TcpExt.TCPFastRetrans = value
|
---|
286 | case "TCPSlowStartRetrans":
|
---|
287 | procNetstat.TcpExt.TCPSlowStartRetrans = value
|
---|
288 | case "TCPTimeouts":
|
---|
289 | procNetstat.TcpExt.TCPTimeouts = value
|
---|
290 | case "TCPLossProbes":
|
---|
291 | procNetstat.TcpExt.TCPLossProbes = value
|
---|
292 | case "TCPLossProbeRecovery":
|
---|
293 | procNetstat.TcpExt.TCPLossProbeRecovery = value
|
---|
294 | case "TCPRenoRecoveryFail":
|
---|
295 | procNetstat.TcpExt.TCPRenoRecoveryFail = value
|
---|
296 | case "TCPSackRecoveryFail":
|
---|
297 | procNetstat.TcpExt.TCPSackRecoveryFail = value
|
---|
298 | case "TCPRcvCollapsed":
|
---|
299 | procNetstat.TcpExt.TCPRcvCollapsed = value
|
---|
300 | case "TCPDSACKOldSent":
|
---|
301 | procNetstat.TcpExt.TCPDSACKOldSent = value
|
---|
302 | case "TCPDSACKOfoSent":
|
---|
303 | procNetstat.TcpExt.TCPDSACKOfoSent = value
|
---|
304 | case "TCPDSACKRecv":
|
---|
305 | procNetstat.TcpExt.TCPDSACKRecv = value
|
---|
306 | case "TCPDSACKOfoRecv":
|
---|
307 | procNetstat.TcpExt.TCPDSACKOfoRecv = value
|
---|
308 | case "TCPAbortOnData":
|
---|
309 | procNetstat.TcpExt.TCPAbortOnData = value
|
---|
310 | case "TCPAbortOnClose":
|
---|
311 | procNetstat.TcpExt.TCPAbortOnClose = value
|
---|
312 | case "TCPDeferAcceptDrop":
|
---|
313 | procNetstat.TcpExt.TCPDeferAcceptDrop = value
|
---|
314 | case "IPReversePathFilter":
|
---|
315 | procNetstat.TcpExt.IPReversePathFilter = value
|
---|
316 | case "TCPTimeWaitOverflow":
|
---|
317 | procNetstat.TcpExt.TCPTimeWaitOverflow = value
|
---|
318 | case "TCPReqQFullDoCookies":
|
---|
319 | procNetstat.TcpExt.TCPReqQFullDoCookies = value
|
---|
320 | case "TCPReqQFullDrop":
|
---|
321 | procNetstat.TcpExt.TCPReqQFullDrop = value
|
---|
322 | case "TCPRetransFail":
|
---|
323 | procNetstat.TcpExt.TCPRetransFail = value
|
---|
324 | case "TCPRcvCoalesce":
|
---|
325 | procNetstat.TcpExt.TCPRcvCoalesce = value
|
---|
326 | case "TCPOFOQueue":
|
---|
327 | procNetstat.TcpExt.TCPOFOQueue = value
|
---|
328 | case "TCPOFODrop":
|
---|
329 | procNetstat.TcpExt.TCPOFODrop = value
|
---|
330 | case "TCPOFOMerge":
|
---|
331 | procNetstat.TcpExt.TCPOFOMerge = value
|
---|
332 | case "TCPChallengeACK":
|
---|
333 | procNetstat.TcpExt.TCPChallengeACK = value
|
---|
334 | case "TCPSYNChallenge":
|
---|
335 | procNetstat.TcpExt.TCPSYNChallenge = value
|
---|
336 | case "TCPFastOpenActive":
|
---|
337 | procNetstat.TcpExt.TCPFastOpenActive = value
|
---|
338 | case "TCPFastOpenActiveFail":
|
---|
339 | procNetstat.TcpExt.TCPFastOpenActiveFail = value
|
---|
340 | case "TCPFastOpenPassive":
|
---|
341 | procNetstat.TcpExt.TCPFastOpenPassive = value
|
---|
342 | case "TCPFastOpenPassiveFail":
|
---|
343 | procNetstat.TcpExt.TCPFastOpenPassiveFail = value
|
---|
344 | case "TCPFastOpenListenOverflow":
|
---|
345 | procNetstat.TcpExt.TCPFastOpenListenOverflow = value
|
---|
346 | case "TCPFastOpenCookieReqd":
|
---|
347 | procNetstat.TcpExt.TCPFastOpenCookieReqd = value
|
---|
348 | case "TCPFastOpenBlackhole":
|
---|
349 | procNetstat.TcpExt.TCPFastOpenBlackhole = value
|
---|
350 | case "TCPSpuriousRtxHostQueues":
|
---|
351 | procNetstat.TcpExt.TCPSpuriousRtxHostQueues = value
|
---|
352 | case "BusyPollRxPackets":
|
---|
353 | procNetstat.TcpExt.BusyPollRxPackets = value
|
---|
354 | case "TCPAutoCorking":
|
---|
355 | procNetstat.TcpExt.TCPAutoCorking = value
|
---|
356 | case "TCPFromZeroWindowAdv":
|
---|
357 | procNetstat.TcpExt.TCPFromZeroWindowAdv = value
|
---|
358 | case "TCPToZeroWindowAdv":
|
---|
359 | procNetstat.TcpExt.TCPToZeroWindowAdv = value
|
---|
360 | case "TCPWantZeroWindowAdv":
|
---|
361 | procNetstat.TcpExt.TCPWantZeroWindowAdv = value
|
---|
362 | case "TCPSynRetrans":
|
---|
363 | procNetstat.TcpExt.TCPSynRetrans = value
|
---|
364 | case "TCPOrigDataSent":
|
---|
365 | procNetstat.TcpExt.TCPOrigDataSent = value
|
---|
366 | case "TCPHystartTrainDetect":
|
---|
367 | procNetstat.TcpExt.TCPHystartTrainDetect = value
|
---|
368 | case "TCPHystartTrainCwnd":
|
---|
369 | procNetstat.TcpExt.TCPHystartTrainCwnd = value
|
---|
370 | case "TCPHystartDelayDetect":
|
---|
371 | procNetstat.TcpExt.TCPHystartDelayDetect = value
|
---|
372 | case "TCPHystartDelayCwnd":
|
---|
373 | procNetstat.TcpExt.TCPHystartDelayCwnd = value
|
---|
374 | case "TCPACKSkippedSynRecv":
|
---|
375 | procNetstat.TcpExt.TCPACKSkippedSynRecv = value
|
---|
376 | case "TCPACKSkippedPAWS":
|
---|
377 | procNetstat.TcpExt.TCPACKSkippedPAWS = value
|
---|
378 | case "TCPACKSkippedSeq":
|
---|
379 | procNetstat.TcpExt.TCPACKSkippedSeq = value
|
---|
380 | case "TCPACKSkippedFinWait2":
|
---|
381 | procNetstat.TcpExt.TCPACKSkippedFinWait2 = value
|
---|
382 | case "TCPACKSkippedTimeWait":
|
---|
383 | procNetstat.TcpExt.TCPACKSkippedTimeWait = value
|
---|
384 | case "TCPACKSkippedChallenge":
|
---|
385 | procNetstat.TcpExt.TCPACKSkippedChallenge = value
|
---|
386 | case "TCPWinProbe":
|
---|
387 | procNetstat.TcpExt.TCPWinProbe = value
|
---|
388 | case "TCPKeepAlive":
|
---|
389 | procNetstat.TcpExt.TCPKeepAlive = value
|
---|
390 | case "TCPMTUPFail":
|
---|
391 | procNetstat.TcpExt.TCPMTUPFail = value
|
---|
392 | case "TCPMTUPSuccess":
|
---|
393 | procNetstat.TcpExt.TCPMTUPSuccess = value
|
---|
394 | case "TCPWqueueTooBig":
|
---|
395 | procNetstat.TcpExt.TCPWqueueTooBig = value
|
---|
396 | }
|
---|
397 | case "IpExt":
|
---|
398 | switch key {
|
---|
399 | case "InNoRoutes":
|
---|
400 | procNetstat.IpExt.InNoRoutes = value
|
---|
401 | case "InTruncatedPkts":
|
---|
402 | procNetstat.IpExt.InTruncatedPkts = value
|
---|
403 | case "InMcastPkts":
|
---|
404 | procNetstat.IpExt.InMcastPkts = value
|
---|
405 | case "OutMcastPkts":
|
---|
406 | procNetstat.IpExt.OutMcastPkts = value
|
---|
407 | case "InBcastPkts":
|
---|
408 | procNetstat.IpExt.InBcastPkts = value
|
---|
409 | case "OutBcastPkts":
|
---|
410 | procNetstat.IpExt.OutBcastPkts = value
|
---|
411 | case "InOctets":
|
---|
412 | procNetstat.IpExt.InOctets = value
|
---|
413 | case "OutOctets":
|
---|
414 | procNetstat.IpExt.OutOctets = value
|
---|
415 | case "InMcastOctets":
|
---|
416 | procNetstat.IpExt.InMcastOctets = value
|
---|
417 | case "OutMcastOctets":
|
---|
418 | procNetstat.IpExt.OutMcastOctets = value
|
---|
419 | case "InBcastOctets":
|
---|
420 | procNetstat.IpExt.InBcastOctets = value
|
---|
421 | case "OutBcastOctets":
|
---|
422 | procNetstat.IpExt.OutBcastOctets = value
|
---|
423 | case "InCsumErrors":
|
---|
424 | procNetstat.IpExt.InCsumErrors = value
|
---|
425 | case "InNoECTPkts":
|
---|
426 | procNetstat.IpExt.InNoECTPkts = value
|
---|
427 | case "InECT1Pkts":
|
---|
428 | procNetstat.IpExt.InECT1Pkts = value
|
---|
429 | case "InECT0Pkts":
|
---|
430 | procNetstat.IpExt.InECT0Pkts = value
|
---|
431 | case "InCEPkts":
|
---|
432 | procNetstat.IpExt.InCEPkts = value
|
---|
433 | case "ReasmOverlaps":
|
---|
434 | procNetstat.IpExt.ReasmOverlaps = value
|
---|
435 | }
|
---|
436 | }
|
---|
437 | }
|
---|
438 | }
|
---|
439 | return procNetstat, scanner.Err()
|
---|
440 | }
|
---|