...

Source file src/github.com/prometheus/procfs/net_wireless.go

Documentation: github.com/prometheus/procfs

     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  // Wireless models the content of /proc/net/wireless.
    28  type Wireless struct {
    29  	Name string
    30  
    31  	// Status is the current 4-digit hex value status of the interface.
    32  	Status uint64
    33  
    34  	// QualityLink is the link quality.
    35  	QualityLink int
    36  
    37  	// QualityLevel is the signal gain (dBm).
    38  	QualityLevel int
    39  
    40  	// QualityNoise is the signal noise baseline (dBm).
    41  	QualityNoise int
    42  
    43  	// DiscardedNwid is the number of discarded packets with wrong nwid/essid.
    44  	DiscardedNwid int
    45  
    46  	// DiscardedCrypt is the number of discarded packets with wrong code/decode (WEP).
    47  	DiscardedCrypt int
    48  
    49  	// DiscardedFrag is the number of discarded packets that can't perform MAC reassembly.
    50  	DiscardedFrag int
    51  
    52  	// DiscardedRetry is the number of discarded packets that reached max MAC retries.
    53  	DiscardedRetry int
    54  
    55  	// DiscardedMisc is the number of discarded packets for other reasons.
    56  	DiscardedMisc int
    57  
    58  	// MissedBeacon is the number of missed beacons/superframe.
    59  	MissedBeacon int
    60  }
    61  
    62  // Wireless returns kernel wireless statistics.
    63  func (fs FS) Wireless() ([]*Wireless, error) {
    64  	b, err := util.ReadFileNoStat(fs.proc.Path("net/wireless"))
    65  	if err != nil {
    66  		return nil, err
    67  	}
    68  
    69  	m, err := parseWireless(bytes.NewReader(b))
    70  	if err != nil {
    71  		return nil, fmt.Errorf("%s: wireless: %w", ErrFileParse, err)
    72  	}
    73  
    74  	return m, nil
    75  }
    76  
    77  // parseWireless parses the contents of /proc/net/wireless.
    78  /*
    79  Inter-| sta-|   Quality        |   Discarded packets               | Missed | WE
    80  face | tus | link level noise |  nwid  crypt   frag  retry   misc | beacon | 22
    81   eth1: 0000    5.  -256.  -10.       0      1      0     3      0        0
    82   eth2: 0000    5.  -256.  -20.       0      2      0     4      0        0
    83  */
    84  func parseWireless(r io.Reader) ([]*Wireless, error) {
    85  	var (
    86  		interfaces []*Wireless
    87  		scanner    = bufio.NewScanner(r)
    88  	)
    89  
    90  	for n := 0; scanner.Scan(); n++ {
    91  		// Skip the 2 header lines.
    92  		if n < 2 {
    93  			continue
    94  		}
    95  
    96  		line := scanner.Text()
    97  
    98  		parts := strings.Split(line, ":")
    99  		if len(parts) != 2 {
   100  			return nil, fmt.Errorf("%w: expected 2 parts after splitting line by ':', got %d for line %q", ErrFileParse, len(parts), line)
   101  		}
   102  
   103  		name := strings.TrimSpace(parts[0])
   104  		stats := strings.Fields(parts[1])
   105  
   106  		if len(stats) < 10 {
   107  			return nil, fmt.Errorf("%w: invalid number of fields in line %d, expected 10+, got %d: %q", ErrFileParse, n, len(stats), line)
   108  		}
   109  
   110  		status, err := strconv.ParseUint(stats[0], 16, 16)
   111  		if err != nil {
   112  			return nil, fmt.Errorf("%w: invalid status in line %d: %q", ErrFileParse, n, line)
   113  		}
   114  
   115  		qlink, err := strconv.Atoi(strings.TrimSuffix(stats[1], "."))
   116  		if err != nil {
   117  			return nil, fmt.Errorf("%s: parse Quality:link as integer %q: %w", ErrFileParse, qlink, err)
   118  		}
   119  
   120  		qlevel, err := strconv.Atoi(strings.TrimSuffix(stats[2], "."))
   121  		if err != nil {
   122  			return nil, fmt.Errorf("%s: Quality:level as integer %q: %w", ErrFileParse, qlevel, err)
   123  		}
   124  
   125  		qnoise, err := strconv.Atoi(strings.TrimSuffix(stats[3], "."))
   126  		if err != nil {
   127  			return nil, fmt.Errorf("%s: Quality:noise as integer %q: %w", ErrFileParse, qnoise, err)
   128  		}
   129  
   130  		dnwid, err := strconv.Atoi(stats[4])
   131  		if err != nil {
   132  			return nil, fmt.Errorf("%s: Discarded:nwid as integer %q: %w", ErrFileParse, dnwid, err)
   133  		}
   134  
   135  		dcrypt, err := strconv.Atoi(stats[5])
   136  		if err != nil {
   137  			return nil, fmt.Errorf("%s: Discarded:crypt as integer %q: %w", ErrFileParse, dcrypt, err)
   138  		}
   139  
   140  		dfrag, err := strconv.Atoi(stats[6])
   141  		if err != nil {
   142  			return nil, fmt.Errorf("%s: Discarded:frag as integer %q: %w", ErrFileParse, dfrag, err)
   143  		}
   144  
   145  		dretry, err := strconv.Atoi(stats[7])
   146  		if err != nil {
   147  			return nil, fmt.Errorf("%s: Discarded:retry as integer %q: %w", ErrFileParse, dretry, err)
   148  		}
   149  
   150  		dmisc, err := strconv.Atoi(stats[8])
   151  		if err != nil {
   152  			return nil, fmt.Errorf("%s: Discarded:misc as integer %q: %w", ErrFileParse, dmisc, err)
   153  		}
   154  
   155  		mbeacon, err := strconv.Atoi(stats[9])
   156  		if err != nil {
   157  			return nil, fmt.Errorf("%s: Missed:beacon as integer %q: %w", ErrFileParse, mbeacon, err)
   158  		}
   159  
   160  		w := &Wireless{
   161  			Name:           name,
   162  			Status:         status,
   163  			QualityLink:    qlink,
   164  			QualityLevel:   qlevel,
   165  			QualityNoise:   qnoise,
   166  			DiscardedNwid:  dnwid,
   167  			DiscardedCrypt: dcrypt,
   168  			DiscardedFrag:  dfrag,
   169  			DiscardedRetry: dretry,
   170  			DiscardedMisc:  dmisc,
   171  			MissedBeacon:   mbeacon,
   172  		}
   173  
   174  		interfaces = append(interfaces, w)
   175  	}
   176  
   177  	if err := scanner.Err(); err != nil {
   178  		return nil, fmt.Errorf("%s: Failed to scan /proc/net/wireless: %w", ErrFileRead, err)
   179  	}
   180  
   181  	return interfaces, nil
   182  }
   183  

View as plain text