View Javadoc
1   /*
2    * Copyright 2020-2022 The OSHI Project Contributors
3    * SPDX-License-Identifier: MIT
4    */
5   package oshi.software.os.unix.solaris;
6   
7   import java.util.List;
8   
9   import oshi.annotation.concurrent.ThreadSafe;
10  import oshi.software.common.AbstractInternetProtocolStats;
11  import oshi.util.ExecutingCommand;
12  import oshi.util.ParseUtil;
13  
14  /**
15   * Internet Protocol Stats implementation
16   */
17  @ThreadSafe
18  public class SolarisInternetProtocolStats extends AbstractInternetProtocolStats {
19  
20      @Override
21      public TcpStats getTCPv4Stats() {
22          return getTcpStats();
23      }
24  
25      @Override
26      public UdpStats getUDPv4Stats() {
27          return getUdpStats();
28      }
29  
30      private static TcpStats getTcpStats() {
31          long connectionsEstablished = 0;
32          long connectionsActive = 0;
33          long connectionsPassive = 0;
34          long connectionFailures = 0;
35          long connectionsReset = 0;
36          long segmentsSent = 0;
37          long segmentsReceived = 0;
38          long segmentsRetransmitted = 0;
39          long inErrors = 0;
40          long outResets = 0;
41          List<String> netstat = ExecutingCommand.runNative("netstat -s -P tcp");
42          // append IP
43          netstat.addAll(ExecutingCommand.runNative("netstat -s -P ip"));
44          for (String s : netstat) {
45              // Two stats per line. Split the strings by index of "tcp"
46              String[] stats = splitOnPrefix(s, "tcp");
47              // Now of form tcpXX = 123
48              for (String stat : stats) {
49                  if (stat != null) {
50                      String[] split = stat.split("=");
51                      if (split.length == 2) {
52                          switch (split[0].trim()) {
53                          case "tcpCurrEstab":
54                              connectionsEstablished = ParseUtil.parseLongOrDefault(split[1].trim(), 0L);
55                              break;
56                          case "tcpActiveOpens":
57                              connectionsActive = ParseUtil.parseLongOrDefault(split[1].trim(), 0L);
58                              break;
59                          case "tcpPassiveOpens":
60                              connectionsPassive = ParseUtil.parseLongOrDefault(split[1].trim(), 0L);
61                              break;
62                          case "tcpAttemptFails":
63                              connectionFailures = ParseUtil.parseLongOrDefault(split[1].trim(), 0L);
64                              break;
65                          case "tcpEstabResets":
66                              connectionsReset = ParseUtil.parseLongOrDefault(split[1].trim(), 0L);
67                              break;
68                          case "tcpOutSegs":
69                              segmentsSent = ParseUtil.parseLongOrDefault(split[1].trim(), 0L);
70                              break;
71                          case "tcpInSegs":
72                              segmentsReceived = ParseUtil.parseLongOrDefault(split[1].trim(), 0L);
73                              break;
74                          case "tcpRetransSegs":
75                              segmentsRetransmitted = ParseUtil.parseLongOrDefault(split[1].trim(), 0L);
76                              break;
77                          case "tcpInErr":
78                              // doesn't have tcp in second column
79                              inErrors = ParseUtil.getFirstIntValue(split[1].trim());
80                              break;
81                          case "tcpOutRsts":
82                              outResets = ParseUtil.parseLongOrDefault(split[1].trim(), 0L);
83                              break;
84                          default:
85                              break;
86                          }
87                      }
88                  }
89              }
90          }
91          return new TcpStats(connectionsEstablished, connectionsActive, connectionsPassive, connectionFailures,
92                  connectionsReset, segmentsSent, segmentsReceived, segmentsRetransmitted, inErrors, outResets);
93      }
94  
95      private static UdpStats getUdpStats() {
96          long datagramsSent = 0;
97          long datagramsReceived = 0;
98          long datagramsNoPort = 0;
99          long datagramsReceivedErrors = 0;
100         List<String> netstat = ExecutingCommand.runNative("netstat -s -P udp");
101         // append IP
102         netstat.addAll(ExecutingCommand.runNative("netstat -s -P ip"));
103         for (String s : netstat) {
104             // Two stats per line. Split the strings by index of "udp"
105             String[] stats = splitOnPrefix(s, "udp");
106             // Now of form udpXX = 123
107             for (String stat : stats) {
108                 if (stat != null) {
109                     String[] split = stat.split("=");
110                     if (split.length == 2) {
111                         switch (split[0].trim()) {
112                         case "udpOutDatagrams":
113                             datagramsSent = ParseUtil.parseLongOrDefault(split[1].trim(), 0L);
114                             break;
115                         case "udpInDatagrams":
116                             datagramsReceived = ParseUtil.parseLongOrDefault(split[1].trim(), 0L);
117                             break;
118                         case "udpNoPorts":
119                             datagramsNoPort = ParseUtil.parseLongOrDefault(split[1].trim(), 0L);
120                             break;
121                         case "udpInErrors":
122                             datagramsReceivedErrors = ParseUtil.parseLongOrDefault(split[1].trim(), 0L);
123                             break;
124                         default:
125                             break;
126                         }
127                     }
128                 }
129             }
130         }
131         return new UdpStats(datagramsSent, datagramsReceived, datagramsNoPort, datagramsReceivedErrors);
132     }
133 
134     private static String[] splitOnPrefix(String s, String prefix) {
135         String[] stats = new String[2];
136         int first = s.indexOf(prefix);
137         if (first >= 0) {
138             int second = s.indexOf(prefix, first + 1);
139             if (second >= 0) {
140                 stats[0] = s.substring(first, second).trim();
141                 stats[1] = s.substring(second).trim();
142             } else {
143                 stats[0] = s.substring(first).trim();
144             }
145         }
146         return stats;
147     }
148 }