View Javadoc
1   /*
2    * Copyright 2017-2022 The OSHI Project Contributors
3    * SPDX-License-Identifier: MIT
4    */
5   package oshi.software.os.linux;
6   
7   import static com.sun.jna.platform.unix.LibCAPI.HOST_NAME_MAX;
8   
9   import java.net.InetAddress;
10  import java.net.UnknownHostException;
11  import java.util.List;
12  
13  import org.slf4j.Logger;
14  import org.slf4j.LoggerFactory;
15  
16  import com.sun.jna.Native;
17  import com.sun.jna.platform.linux.LibC;
18  
19  import oshi.annotation.concurrent.ThreadSafe;
20  import oshi.jna.ByRef.CloseablePointerByReference;
21  import oshi.jna.platform.linux.LinuxLibc;
22  import oshi.jna.platform.unix.CLibrary;
23  import oshi.jna.platform.unix.CLibrary.Addrinfo;
24  import oshi.software.common.AbstractNetworkParams;
25  import oshi.util.ExecutingCommand;
26  import oshi.util.ParseUtil;
27  
28  /**
29   * LinuxNetworkParams class.
30   */
31  @ThreadSafe
32  final class LinuxNetworkParams extends AbstractNetworkParams {
33  
34      private static final Logger LOG = LoggerFactory.getLogger(LinuxNetworkParams.class);
35  
36      private static final LinuxLibc LIBC = LinuxLibc.INSTANCE;
37  
38      private static final String IPV4_DEFAULT_DEST = "0.0.0.0"; // NOSONAR
39      private static final String IPV6_DEFAULT_DEST = "::/0";
40  
41      @Override
42      public String getDomainName() {
43          try (Addrinfo hint = new Addrinfo()) {
44              hint.ai_flags = CLibrary.AI_CANONNAME;
45              String hostname = "";
46              try {
47                  hostname = InetAddress.getLocalHost().getHostName();
48              } catch (UnknownHostException e) {
49                  LOG.warn("Unknown host exception when getting address of local host: {}", e.getMessage());
50                  return "";
51              }
52              try (CloseablePointerByReference ptr = new CloseablePointerByReference()) {
53                  int res = LIBC.getaddrinfo(hostname, null, hint, ptr);
54                  if (res > 0) {
55                      if (LOG.isErrorEnabled()) {
56                          LOG.error("Failed getaddrinfo(): {}", LIBC.gai_strerror(res));
57                      }
58                      return "";
59                  }
60                  try (Addrinfo info = new Addrinfo(ptr.getValue())) {
61                      return info.ai_canonname == null ? hostname : info.ai_canonname.trim();
62                  }
63              }
64          }
65      }
66  
67      @Override
68      public String getHostName() {
69          byte[] hostnameBuffer = new byte[HOST_NAME_MAX + 1];
70          if (0 != LibC.INSTANCE.gethostname(hostnameBuffer, hostnameBuffer.length)) {
71              return super.getHostName();
72          }
73          return Native.toString(hostnameBuffer);
74      }
75  
76      @Override
77      public String getIpv4DefaultGateway() {
78          List<String> routes = ExecutingCommand.runNative("route -A inet -n");
79          if (routes.size() <= 2) {
80              return "";
81          }
82  
83          String gateway = "";
84          int minMetric = Integer.MAX_VALUE;
85  
86          for (int i = 2; i < routes.size(); i++) {
87              String[] fields = ParseUtil.whitespaces.split(routes.get(i));
88              if (fields.length > 4 && fields[0].equals(IPV4_DEFAULT_DEST)) {
89                  boolean isGateway = fields[3].indexOf('G') != -1;
90                  int metric = ParseUtil.parseIntOrDefault(fields[4], Integer.MAX_VALUE);
91                  if (isGateway && metric < minMetric) {
92                      minMetric = metric;
93                      gateway = fields[1];
94                  }
95              }
96          }
97          return gateway;
98      }
99  
100     @Override
101     public String getIpv6DefaultGateway() {
102         List<String> routes = ExecutingCommand.runNative("route -A inet6 -n");
103         if (routes.size() <= 2) {
104             return "";
105         }
106 
107         String gateway = "";
108         int minMetric = Integer.MAX_VALUE;
109 
110         for (int i = 2; i < routes.size(); i++) {
111             String[] fields = ParseUtil.whitespaces.split(routes.get(i));
112             if (fields.length > 3 && fields[0].equals(IPV6_DEFAULT_DEST)) {
113                 boolean isGateway = fields[2].indexOf('G') != -1;
114                 int metric = ParseUtil.parseIntOrDefault(fields[3], Integer.MAX_VALUE);
115                 if (isGateway && metric < minMetric) {
116                     minMetric = metric;
117                     gateway = fields[1];
118                 }
119             }
120         }
121         return gateway;
122     }
123 }