1
2
3
4
5 package oshi.hardware.platform.linux;
6
7 import static oshi.software.os.linux.LinuxOperatingSystem.HAS_UDEV;
8
9 import java.io.File;
10 import java.net.NetworkInterface;
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.Map;
14
15 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory;
17
18 import com.sun.jna.platform.linux.Udev;
19 import com.sun.jna.platform.linux.Udev.UdevContext;
20 import com.sun.jna.platform.linux.Udev.UdevDevice;
21
22 import oshi.annotation.concurrent.ThreadSafe;
23 import oshi.hardware.NetworkIF;
24 import oshi.hardware.common.AbstractNetworkIF;
25 import oshi.util.FileUtil;
26 import oshi.util.Util;
27 import oshi.util.platform.linux.SysPath;
28
29
30
31
32 @ThreadSafe
33 public final class LinuxNetworkIF extends AbstractNetworkIF {
34
35 private static final Logger LOG = LoggerFactory.getLogger(LinuxNetworkIF.class);
36
37 private int ifType;
38 private boolean connectorPresent;
39 private long bytesRecv;
40 private long bytesSent;
41 private long packetsRecv;
42 private long packetsSent;
43 private long inErrors;
44 private long outErrors;
45 private long inDrops;
46 private long collisions;
47 private long speed;
48 private long timeStamp;
49 private String ifAlias = "";
50 private IfOperStatus ifOperStatus = IfOperStatus.UNKNOWN;
51
52 public LinuxNetworkIF(NetworkInterface netint) throws InstantiationException {
53 super(netint, queryIfModel(netint));
54 updateAttributes();
55 }
56
57 private static String queryIfModel(NetworkInterface netint) {
58 String name = netint.getName();
59 if (!HAS_UDEV) {
60 return queryIfModelFromSysfs(name);
61 }
62 UdevContext udev = Udev.INSTANCE.udev_new();
63 if (udev != null) {
64 try {
65 UdevDevice device = udev.deviceNewFromSyspath(SysPath.NET + name);
66 if (device != null) {
67 try {
68 String devVendor = device.getPropertyValue("ID_VENDOR_FROM_DATABASE");
69 String devModel = device.getPropertyValue("ID_MODEL_FROM_DATABASE");
70 if (!Util.isBlank(devModel)) {
71 if (!Util.isBlank(devVendor)) {
72 return devVendor + " " + devModel;
73 }
74 return devModel;
75 }
76 } finally {
77 device.unref();
78 }
79 }
80 } finally {
81 udev.unref();
82 }
83 }
84 return name;
85 }
86
87 private static String queryIfModelFromSysfs(String name) {
88 Map<String, String> uevent = FileUtil.getKeyValueMapFromFile(SysPath.NET + name + "/uevent", "=");
89 String devVendor = uevent.get("ID_VENDOR_FROM_DATABASE");
90 String devModel = uevent.get("ID_MODEL_FROM_DATABASE");
91 if (!Util.isBlank(devModel)) {
92 if (!Util.isBlank(devVendor)) {
93 return devVendor + " " + devModel;
94 }
95 return devModel;
96 }
97 return name;
98 }
99
100
101
102
103
104
105
106 public static List<NetworkIF> getNetworks(boolean includeLocalInterfaces) {
107 List<NetworkIF> ifList = new ArrayList<>();
108 for (NetworkInterface ni : getNetworkInterfaces(includeLocalInterfaces)) {
109 try {
110 ifList.add(new LinuxNetworkIF(ni));
111 } catch (InstantiationException e) {
112 LOG.debug("Network Interface Instantiation failed: {}", e.getMessage());
113 }
114 }
115 return ifList;
116 }
117
118 @Override
119 public int getIfType() {
120 return this.ifType;
121 }
122
123 @Override
124 public boolean isConnectorPresent() {
125 return this.connectorPresent;
126 }
127
128 @Override
129 public long getBytesRecv() {
130 return this.bytesRecv;
131 }
132
133 @Override
134 public long getBytesSent() {
135 return this.bytesSent;
136 }
137
138 @Override
139 public long getPacketsRecv() {
140 return this.packetsRecv;
141 }
142
143 @Override
144 public long getPacketsSent() {
145 return this.packetsSent;
146 }
147
148 @Override
149 public long getInErrors() {
150 return this.inErrors;
151 }
152
153 @Override
154 public long getOutErrors() {
155 return this.outErrors;
156 }
157
158 @Override
159 public long getInDrops() {
160 return this.inDrops;
161 }
162
163 @Override
164 public long getCollisions() {
165 return this.collisions;
166 }
167
168 @Override
169 public long getSpeed() {
170 return this.speed;
171 }
172
173 @Override
174 public long getTimeStamp() {
175 return this.timeStamp;
176 }
177
178 @Override
179 public String getIfAlias() {
180 return ifAlias;
181 }
182
183 @Override
184 public IfOperStatus getIfOperStatus() {
185 return ifOperStatus;
186 }
187
188 @Override
189 public boolean updateAttributes() {
190 String name = SysPath.NET + getName();
191 try {
192 File ifDir = new File(name + "/statistics");
193 if (!ifDir.isDirectory()) {
194 return false;
195 }
196 } catch (SecurityException e) {
197 return false;
198 }
199
200 this.timeStamp = System.currentTimeMillis();
201 this.ifType = FileUtil.getIntFromFile(name + "/type");
202 this.connectorPresent = FileUtil.getIntFromFile(name + "/carrier") > 0;
203 this.bytesSent = FileUtil.getUnsignedLongFromFile(name + "/statistics/tx_bytes");
204 this.bytesRecv = FileUtil.getUnsignedLongFromFile(name + "/statistics/rx_bytes");
205 this.packetsSent = FileUtil.getUnsignedLongFromFile(name + "/statistics/tx_packets");
206 this.packetsRecv = FileUtil.getUnsignedLongFromFile(name + "/statistics/rx_packets");
207 this.outErrors = FileUtil.getUnsignedLongFromFile(name + "/statistics/tx_errors");
208 this.inErrors = FileUtil.getUnsignedLongFromFile(name + "/statistics/rx_errors");
209 this.collisions = FileUtil.getUnsignedLongFromFile(name + "/statistics/collisions");
210 this.inDrops = FileUtil.getUnsignedLongFromFile(name + "/statistics/rx_dropped");
211 long speedMbps = FileUtil.getUnsignedLongFromFile(name + "/speed");
212
213 this.speed = speedMbps < 0 ? 0 : speedMbps * 1000000L;
214 this.ifAlias = FileUtil.getStringFromFile(name + "/ifalias");
215 this.ifOperStatus = parseIfOperStatus(FileUtil.getStringFromFile(name + "/operstate"));
216
217 return true;
218 }
219
220 private static IfOperStatus parseIfOperStatus(String operState) {
221 switch (operState) {
222 case "up":
223 return IfOperStatus.UP;
224 case "down":
225 return IfOperStatus.DOWN;
226 case "testing":
227 return IfOperStatus.TESTING;
228 case "dormant":
229 return IfOperStatus.DORMANT;
230 case "notpresent":
231 return IfOperStatus.NOT_PRESENT;
232 case "lowerlayerdown":
233 return IfOperStatus.LOWER_LAYER_DOWN;
234 case "unknown":
235 default:
236 return IfOperStatus.UNKNOWN;
237 }
238 }
239 }