| Abhay Kumar | a2ae599 | 2025-11-10 14:02:24 +0000 | [diff] [blame^] | 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 | "errors" |
| 20 | "io" |
| 21 | "os" |
| 22 | "strconv" |
| 23 | "strings" |
| 24 | |
| 25 | "github.com/prometheus/procfs/internal/util" |
| 26 | ) |
| 27 | |
| 28 | // ProcSnmp6 models the content of /proc/<pid>/net/snmp6. |
| 29 | type ProcSnmp6 struct { |
| 30 | // The process ID. |
| 31 | PID int |
| 32 | Ip6 |
| 33 | Icmp6 |
| 34 | Udp6 |
| 35 | UdpLite6 |
| 36 | } |
| 37 | |
| 38 | type Ip6 struct { // nolint:revive |
| 39 | InReceives *float64 |
| 40 | InHdrErrors *float64 |
| 41 | InTooBigErrors *float64 |
| 42 | InNoRoutes *float64 |
| 43 | InAddrErrors *float64 |
| 44 | InUnknownProtos *float64 |
| 45 | InTruncatedPkts *float64 |
| 46 | InDiscards *float64 |
| 47 | InDelivers *float64 |
| 48 | OutForwDatagrams *float64 |
| 49 | OutRequests *float64 |
| 50 | OutDiscards *float64 |
| 51 | OutNoRoutes *float64 |
| 52 | ReasmTimeout *float64 |
| 53 | ReasmReqds *float64 |
| 54 | ReasmOKs *float64 |
| 55 | ReasmFails *float64 |
| 56 | FragOKs *float64 |
| 57 | FragFails *float64 |
| 58 | FragCreates *float64 |
| 59 | InMcastPkts *float64 |
| 60 | OutMcastPkts *float64 |
| 61 | InOctets *float64 |
| 62 | OutOctets *float64 |
| 63 | InMcastOctets *float64 |
| 64 | OutMcastOctets *float64 |
| 65 | InBcastOctets *float64 |
| 66 | OutBcastOctets *float64 |
| 67 | InNoECTPkts *float64 |
| 68 | InECT1Pkts *float64 |
| 69 | InECT0Pkts *float64 |
| 70 | InCEPkts *float64 |
| 71 | } |
| 72 | |
| 73 | type Icmp6 struct { |
| 74 | InMsgs *float64 |
| 75 | InErrors *float64 |
| 76 | OutMsgs *float64 |
| 77 | OutErrors *float64 |
| 78 | InCsumErrors *float64 |
| 79 | InDestUnreachs *float64 |
| 80 | InPktTooBigs *float64 |
| 81 | InTimeExcds *float64 |
| 82 | InParmProblems *float64 |
| 83 | InEchos *float64 |
| 84 | InEchoReplies *float64 |
| 85 | InGroupMembQueries *float64 |
| 86 | InGroupMembResponses *float64 |
| 87 | InGroupMembReductions *float64 |
| 88 | InRouterSolicits *float64 |
| 89 | InRouterAdvertisements *float64 |
| 90 | InNeighborSolicits *float64 |
| 91 | InNeighborAdvertisements *float64 |
| 92 | InRedirects *float64 |
| 93 | InMLDv2Reports *float64 |
| 94 | OutDestUnreachs *float64 |
| 95 | OutPktTooBigs *float64 |
| 96 | OutTimeExcds *float64 |
| 97 | OutParmProblems *float64 |
| 98 | OutEchos *float64 |
| 99 | OutEchoReplies *float64 |
| 100 | OutGroupMembQueries *float64 |
| 101 | OutGroupMembResponses *float64 |
| 102 | OutGroupMembReductions *float64 |
| 103 | OutRouterSolicits *float64 |
| 104 | OutRouterAdvertisements *float64 |
| 105 | OutNeighborSolicits *float64 |
| 106 | OutNeighborAdvertisements *float64 |
| 107 | OutRedirects *float64 |
| 108 | OutMLDv2Reports *float64 |
| 109 | InType1 *float64 |
| 110 | InType134 *float64 |
| 111 | InType135 *float64 |
| 112 | InType136 *float64 |
| 113 | InType143 *float64 |
| 114 | OutType133 *float64 |
| 115 | OutType135 *float64 |
| 116 | OutType136 *float64 |
| 117 | OutType143 *float64 |
| 118 | } |
| 119 | |
| 120 | type Udp6 struct { // nolint:revive |
| 121 | InDatagrams *float64 |
| 122 | NoPorts *float64 |
| 123 | InErrors *float64 |
| 124 | OutDatagrams *float64 |
| 125 | RcvbufErrors *float64 |
| 126 | SndbufErrors *float64 |
| 127 | InCsumErrors *float64 |
| 128 | IgnoredMulti *float64 |
| 129 | } |
| 130 | |
| 131 | type UdpLite6 struct { // nolint:revive |
| 132 | InDatagrams *float64 |
| 133 | NoPorts *float64 |
| 134 | InErrors *float64 |
| 135 | OutDatagrams *float64 |
| 136 | RcvbufErrors *float64 |
| 137 | SndbufErrors *float64 |
| 138 | InCsumErrors *float64 |
| 139 | } |
| 140 | |
| 141 | func (p Proc) Snmp6() (ProcSnmp6, error) { |
| 142 | filename := p.path("net/snmp6") |
| 143 | data, err := util.ReadFileNoStat(filename) |
| 144 | if err != nil { |
| 145 | // On systems with IPv6 disabled, this file won't exist. |
| 146 | // Do nothing. |
| 147 | if errors.Is(err, os.ErrNotExist) { |
| 148 | return ProcSnmp6{PID: p.PID}, nil |
| 149 | } |
| 150 | |
| 151 | return ProcSnmp6{PID: p.PID}, err |
| 152 | } |
| 153 | |
| 154 | procSnmp6, err := parseSNMP6Stats(bytes.NewReader(data)) |
| 155 | procSnmp6.PID = p.PID |
| 156 | return procSnmp6, err |
| 157 | } |
| 158 | |
| 159 | // parseSnmp6 parses the metrics from proc/<pid>/net/snmp6 file |
| 160 | // and returns a map contains those metrics. |
| 161 | func parseSNMP6Stats(r io.Reader) (ProcSnmp6, error) { |
| 162 | var ( |
| 163 | scanner = bufio.NewScanner(r) |
| 164 | procSnmp6 = ProcSnmp6{} |
| 165 | ) |
| 166 | |
| 167 | for scanner.Scan() { |
| 168 | stat := strings.Fields(scanner.Text()) |
| 169 | if len(stat) < 2 { |
| 170 | continue |
| 171 | } |
| 172 | // Expect to have "6" in metric name, skip line otherwise |
| 173 | if sixIndex := strings.Index(stat[0], "6"); sixIndex != -1 { |
| 174 | protocol := stat[0][:sixIndex+1] |
| 175 | key := stat[0][sixIndex+1:] |
| 176 | value, err := strconv.ParseFloat(stat[1], 64) |
| 177 | if err != nil { |
| 178 | return procSnmp6, err |
| 179 | } |
| 180 | |
| 181 | switch protocol { |
| 182 | case "Ip6": |
| 183 | switch key { |
| 184 | case "InReceives": |
| 185 | procSnmp6.InReceives = &value |
| 186 | case "InHdrErrors": |
| 187 | procSnmp6.InHdrErrors = &value |
| 188 | case "InTooBigErrors": |
| 189 | procSnmp6.InTooBigErrors = &value |
| 190 | case "InNoRoutes": |
| 191 | procSnmp6.InNoRoutes = &value |
| 192 | case "InAddrErrors": |
| 193 | procSnmp6.InAddrErrors = &value |
| 194 | case "InUnknownProtos": |
| 195 | procSnmp6.InUnknownProtos = &value |
| 196 | case "InTruncatedPkts": |
| 197 | procSnmp6.InTruncatedPkts = &value |
| 198 | case "InDiscards": |
| 199 | procSnmp6.InDiscards = &value |
| 200 | case "InDelivers": |
| 201 | procSnmp6.InDelivers = &value |
| 202 | case "OutForwDatagrams": |
| 203 | procSnmp6.OutForwDatagrams = &value |
| 204 | case "OutRequests": |
| 205 | procSnmp6.OutRequests = &value |
| 206 | case "OutDiscards": |
| 207 | procSnmp6.OutDiscards = &value |
| 208 | case "OutNoRoutes": |
| 209 | procSnmp6.OutNoRoutes = &value |
| 210 | case "ReasmTimeout": |
| 211 | procSnmp6.ReasmTimeout = &value |
| 212 | case "ReasmReqds": |
| 213 | procSnmp6.ReasmReqds = &value |
| 214 | case "ReasmOKs": |
| 215 | procSnmp6.ReasmOKs = &value |
| 216 | case "ReasmFails": |
| 217 | procSnmp6.ReasmFails = &value |
| 218 | case "FragOKs": |
| 219 | procSnmp6.FragOKs = &value |
| 220 | case "FragFails": |
| 221 | procSnmp6.FragFails = &value |
| 222 | case "FragCreates": |
| 223 | procSnmp6.FragCreates = &value |
| 224 | case "InMcastPkts": |
| 225 | procSnmp6.InMcastPkts = &value |
| 226 | case "OutMcastPkts": |
| 227 | procSnmp6.OutMcastPkts = &value |
| 228 | case "InOctets": |
| 229 | procSnmp6.InOctets = &value |
| 230 | case "OutOctets": |
| 231 | procSnmp6.OutOctets = &value |
| 232 | case "InMcastOctets": |
| 233 | procSnmp6.InMcastOctets = &value |
| 234 | case "OutMcastOctets": |
| 235 | procSnmp6.OutMcastOctets = &value |
| 236 | case "InBcastOctets": |
| 237 | procSnmp6.InBcastOctets = &value |
| 238 | case "OutBcastOctets": |
| 239 | procSnmp6.OutBcastOctets = &value |
| 240 | case "InNoECTPkts": |
| 241 | procSnmp6.InNoECTPkts = &value |
| 242 | case "InECT1Pkts": |
| 243 | procSnmp6.InECT1Pkts = &value |
| 244 | case "InECT0Pkts": |
| 245 | procSnmp6.InECT0Pkts = &value |
| 246 | case "InCEPkts": |
| 247 | procSnmp6.InCEPkts = &value |
| 248 | |
| 249 | } |
| 250 | case "Icmp6": |
| 251 | switch key { |
| 252 | case "InMsgs": |
| 253 | procSnmp6.InMsgs = &value |
| 254 | case "InErrors": |
| 255 | procSnmp6.Icmp6.InErrors = &value |
| 256 | case "OutMsgs": |
| 257 | procSnmp6.OutMsgs = &value |
| 258 | case "OutErrors": |
| 259 | procSnmp6.OutErrors = &value |
| 260 | case "InCsumErrors": |
| 261 | procSnmp6.Icmp6.InCsumErrors = &value |
| 262 | case "InDestUnreachs": |
| 263 | procSnmp6.InDestUnreachs = &value |
| 264 | case "InPktTooBigs": |
| 265 | procSnmp6.InPktTooBigs = &value |
| 266 | case "InTimeExcds": |
| 267 | procSnmp6.InTimeExcds = &value |
| 268 | case "InParmProblems": |
| 269 | procSnmp6.InParmProblems = &value |
| 270 | case "InEchos": |
| 271 | procSnmp6.InEchos = &value |
| 272 | case "InEchoReplies": |
| 273 | procSnmp6.InEchoReplies = &value |
| 274 | case "InGroupMembQueries": |
| 275 | procSnmp6.InGroupMembQueries = &value |
| 276 | case "InGroupMembResponses": |
| 277 | procSnmp6.InGroupMembResponses = &value |
| 278 | case "InGroupMembReductions": |
| 279 | procSnmp6.InGroupMembReductions = &value |
| 280 | case "InRouterSolicits": |
| 281 | procSnmp6.InRouterSolicits = &value |
| 282 | case "InRouterAdvertisements": |
| 283 | procSnmp6.InRouterAdvertisements = &value |
| 284 | case "InNeighborSolicits": |
| 285 | procSnmp6.InNeighborSolicits = &value |
| 286 | case "InNeighborAdvertisements": |
| 287 | procSnmp6.InNeighborAdvertisements = &value |
| 288 | case "InRedirects": |
| 289 | procSnmp6.InRedirects = &value |
| 290 | case "InMLDv2Reports": |
| 291 | procSnmp6.InMLDv2Reports = &value |
| 292 | case "OutDestUnreachs": |
| 293 | procSnmp6.OutDestUnreachs = &value |
| 294 | case "OutPktTooBigs": |
| 295 | procSnmp6.OutPktTooBigs = &value |
| 296 | case "OutTimeExcds": |
| 297 | procSnmp6.OutTimeExcds = &value |
| 298 | case "OutParmProblems": |
| 299 | procSnmp6.OutParmProblems = &value |
| 300 | case "OutEchos": |
| 301 | procSnmp6.OutEchos = &value |
| 302 | case "OutEchoReplies": |
| 303 | procSnmp6.OutEchoReplies = &value |
| 304 | case "OutGroupMembQueries": |
| 305 | procSnmp6.OutGroupMembQueries = &value |
| 306 | case "OutGroupMembResponses": |
| 307 | procSnmp6.OutGroupMembResponses = &value |
| 308 | case "OutGroupMembReductions": |
| 309 | procSnmp6.OutGroupMembReductions = &value |
| 310 | case "OutRouterSolicits": |
| 311 | procSnmp6.OutRouterSolicits = &value |
| 312 | case "OutRouterAdvertisements": |
| 313 | procSnmp6.OutRouterAdvertisements = &value |
| 314 | case "OutNeighborSolicits": |
| 315 | procSnmp6.OutNeighborSolicits = &value |
| 316 | case "OutNeighborAdvertisements": |
| 317 | procSnmp6.OutNeighborAdvertisements = &value |
| 318 | case "OutRedirects": |
| 319 | procSnmp6.OutRedirects = &value |
| 320 | case "OutMLDv2Reports": |
| 321 | procSnmp6.OutMLDv2Reports = &value |
| 322 | case "InType1": |
| 323 | procSnmp6.InType1 = &value |
| 324 | case "InType134": |
| 325 | procSnmp6.InType134 = &value |
| 326 | case "InType135": |
| 327 | procSnmp6.InType135 = &value |
| 328 | case "InType136": |
| 329 | procSnmp6.InType136 = &value |
| 330 | case "InType143": |
| 331 | procSnmp6.InType143 = &value |
| 332 | case "OutType133": |
| 333 | procSnmp6.OutType133 = &value |
| 334 | case "OutType135": |
| 335 | procSnmp6.OutType135 = &value |
| 336 | case "OutType136": |
| 337 | procSnmp6.OutType136 = &value |
| 338 | case "OutType143": |
| 339 | procSnmp6.OutType143 = &value |
| 340 | } |
| 341 | case "Udp6": |
| 342 | switch key { |
| 343 | case "InDatagrams": |
| 344 | procSnmp6.Udp6.InDatagrams = &value |
| 345 | case "NoPorts": |
| 346 | procSnmp6.Udp6.NoPorts = &value |
| 347 | case "InErrors": |
| 348 | procSnmp6.Udp6.InErrors = &value |
| 349 | case "OutDatagrams": |
| 350 | procSnmp6.Udp6.OutDatagrams = &value |
| 351 | case "RcvbufErrors": |
| 352 | procSnmp6.Udp6.RcvbufErrors = &value |
| 353 | case "SndbufErrors": |
| 354 | procSnmp6.Udp6.SndbufErrors = &value |
| 355 | case "InCsumErrors": |
| 356 | procSnmp6.Udp6.InCsumErrors = &value |
| 357 | case "IgnoredMulti": |
| 358 | procSnmp6.IgnoredMulti = &value |
| 359 | } |
| 360 | case "UdpLite6": |
| 361 | switch key { |
| 362 | case "InDatagrams": |
| 363 | procSnmp6.UdpLite6.InDatagrams = &value |
| 364 | case "NoPorts": |
| 365 | procSnmp6.UdpLite6.NoPorts = &value |
| 366 | case "InErrors": |
| 367 | procSnmp6.UdpLite6.InErrors = &value |
| 368 | case "OutDatagrams": |
| 369 | procSnmp6.UdpLite6.OutDatagrams = &value |
| 370 | case "RcvbufErrors": |
| 371 | procSnmp6.UdpLite6.RcvbufErrors = &value |
| 372 | case "SndbufErrors": |
| 373 | procSnmp6.UdpLite6.SndbufErrors = &value |
| 374 | case "InCsumErrors": |
| 375 | procSnmp6.UdpLite6.InCsumErrors = &value |
| 376 | } |
| 377 | } |
| 378 | } |
| 379 | } |
| 380 | return procSnmp6, scanner.Err() |
| 381 | } |