View Javadoc
1   /*
2    * Copyright 2020-2022 The OSHI Project Contributors
3    * SPDX-License-Identifier: MIT
4    */
5   package oshi.hardware.platform.unix.solaris;
6   
7   import static oshi.software.os.unix.solaris.SolarisOperatingSystem.HAS_KSTAT2;
8   
9   import java.net.NetworkInterface;
10  import java.util.ArrayList;
11  import java.util.List;
12  
13  import org.slf4j.Logger;
14  import org.slf4j.LoggerFactory;
15  
16  import com.sun.jna.platform.unix.solaris.LibKstat.Kstat;
17  
18  import oshi.annotation.concurrent.ThreadSafe;
19  import oshi.hardware.NetworkIF;
20  import oshi.hardware.common.AbstractNetworkIF;
21  import oshi.util.platform.unix.solaris.KstatUtil;
22  import oshi.util.platform.unix.solaris.KstatUtil.KstatChain;
23  
24  /**
25   * SolarisNetworks class.
26   */
27  @ThreadSafe
28  public final class SolarisNetworkIF extends AbstractNetworkIF {
29  
30      private static final Logger LOG = LoggerFactory.getLogger(SolarisNetworkIF.class);
31  
32      private long bytesRecv;
33      private long bytesSent;
34      private long packetsRecv;
35      private long packetsSent;
36      private long inErrors;
37      private long outErrors;
38      private long inDrops;
39      private long collisions;
40      private long speed;
41      private long timeStamp;
42  
43      public SolarisNetworkIF(NetworkInterface netint) throws InstantiationException {
44          super(netint);
45          updateAttributes();
46      }
47  
48      /**
49       * Gets all network interfaces on this machine
50       *
51       * @param includeLocalInterfaces include local interfaces in the result
52       * @return A list of {@link NetworkIF} objects representing the interfaces
53       */
54      public static List<NetworkIF> getNetworks(boolean includeLocalInterfaces) {
55          List<NetworkIF> ifList = new ArrayList<>();
56          for (NetworkInterface ni : getNetworkInterfaces(includeLocalInterfaces)) {
57              try {
58                  ifList.add(new SolarisNetworkIF(ni));
59              } catch (InstantiationException e) {
60                  LOG.debug("Network Interface Instantiation failed: {}", e.getMessage());
61              }
62          }
63          return ifList;
64      }
65  
66      @Override
67      public long getBytesRecv() {
68          return this.bytesRecv;
69      }
70  
71      @Override
72      public long getBytesSent() {
73          return this.bytesSent;
74      }
75  
76      @Override
77      public long getPacketsRecv() {
78          return this.packetsRecv;
79      }
80  
81      @Override
82      public long getPacketsSent() {
83          return this.packetsSent;
84      }
85  
86      @Override
87      public long getInErrors() {
88          return this.inErrors;
89      }
90  
91      @Override
92      public long getOutErrors() {
93          return this.outErrors;
94      }
95  
96      @Override
97      public long getInDrops() {
98          return this.inDrops;
99      }
100 
101     @Override
102     public long getCollisions() {
103         return this.collisions;
104     }
105 
106     @Override
107     public long getSpeed() {
108         return this.speed;
109     }
110 
111     @Override
112     public long getTimeStamp() {
113         return this.timeStamp;
114     }
115 
116     @Override
117     public boolean updateAttributes() {
118         // Initialize to a sane default value
119         this.timeStamp = System.currentTimeMillis();
120         if (HAS_KSTAT2) {
121             // Use Kstat2 implementation
122             return updateAttributes2();
123         }
124         try (KstatChain kc = KstatUtil.openChain()) {
125             Kstat ksp = kc.lookup("link", -1, getName());
126             if (ksp == null) { // Solaris 10 compatibility
127                 ksp = kc.lookup(null, -1, getName());
128             }
129             if (ksp != null && kc.read(ksp)) {
130                 this.bytesSent = KstatUtil.dataLookupLong(ksp, "obytes64");
131                 this.bytesRecv = KstatUtil.dataLookupLong(ksp, "rbytes64");
132                 this.packetsSent = KstatUtil.dataLookupLong(ksp, "opackets64");
133                 this.packetsRecv = KstatUtil.dataLookupLong(ksp, "ipackets64");
134                 this.outErrors = KstatUtil.dataLookupLong(ksp, "oerrors");
135                 this.inErrors = KstatUtil.dataLookupLong(ksp, "ierrors");
136                 this.collisions = KstatUtil.dataLookupLong(ksp, "collisions");
137                 this.inDrops = KstatUtil.dataLookupLong(ksp, "dl_idrops");
138                 this.speed = KstatUtil.dataLookupLong(ksp, "ifspeed");
139                 // Snap time in ns; convert to ms
140                 this.timeStamp = ksp.ks_snaptime / 1_000_000L;
141                 return true;
142             }
143         }
144         return false;
145     }
146 
147     private boolean updateAttributes2() {
148         Object[] results = KstatUtil.queryKstat2("kstat:/net/link/" + getName() + "/0", "obytes64", "rbytes64",
149                 "opackets64", "ipackets64", "oerrors", "ierrors", "collisions", "dl_idrops", "ifspeed", "snaptime");
150         if (results[results.length - 1] == null) {
151             return false;
152         }
153         this.bytesSent = results[0] == null ? 0L : (long) results[0];
154         this.bytesRecv = results[1] == null ? 0L : (long) results[1];
155         this.packetsSent = results[2] == null ? 0L : (long) results[2];
156         this.packetsRecv = results[3] == null ? 0L : (long) results[3];
157         this.outErrors = results[4] == null ? 0L : (long) results[4];
158         this.collisions = results[5] == null ? 0L : (long) results[5];
159         this.inDrops = results[6] == null ? 0L : (long) results[6];
160         this.speed = results[7] == null ? 0L : (long) results[7];
161         // Snap time in ns; convert to ms
162         this.timeStamp = (long) results[8] / 1_000_000L;
163         return true;
164     }
165 }