[New] Added new NetworkHelper.streamStrolchNetworkInterface()

This now streams over all interfaces, no matter if it is running or not.
This commit is contained in:
Robert von Burg 2023-10-10 16:23:33 +02:00
parent 6fc822fe52
commit da946f1acb
Signed by: eitch
GPG Key ID: 75DB9C85C74331F7
2 changed files with 114 additions and 7 deletions

View File

@ -1,12 +1,19 @@
package li.strolch.utils.helper;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.io.File;
import java.io.IOException;
import java.net.*;
import java.nio.file.Path;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import static java.nio.file.Files.readAllLines;
import static java.nio.file.Files.readString;
import static java.util.Spliterator.ORDERED;
import static java.util.Spliterators.spliteratorUnknownSize;
public class NetworkHelper {
@ -33,6 +40,15 @@ public class NetworkHelper {
return inet4Addresses;
}
public static String formatMacAddress(NetworkInterface networkInterface) {
try {
return formatMacAddress(networkInterface.getHardwareAddress());
} catch (SocketException e) {
throw new IllegalStateException(
"Failed to get hardware address for network interface " + networkInterface.getDisplayName(), e);
}
}
public static String formatMacAddress(byte[] bytes) {
StringBuilder sb = new StringBuilder(17);
for (byte b : bytes) {
@ -42,4 +58,83 @@ public class NetworkHelper {
}
return sb.toString();
}
public static void main(String[] args) throws IOException {
Stream<StrolchNetworkInterface> interfaceStream = streamStrolchNetworkInterface();
interfaceStream.forEach(t -> System.out.printf("%20s: %s%n", t.name(), t.hwAddress()));
}
public static Stream<StrolchNetworkInterface> streamStrolchNetworkInterface() {
if (!System.getProperty("os.name").equals("Linux")) {
Enumeration<NetworkInterface> interfaces = null;
try {
interfaces = NetworkInterface.getNetworkInterfaces();
} catch (SocketException e) {
throw new IllegalStateException("Failed to read network interfaces ", e);
}
return StreamSupport.stream(spliteratorUnknownSize(interfaces.asIterator(), ORDERED), false).map(ni -> {
try {
List<InetAddress> addresses = Collections.list(ni.getInetAddresses());
if (addresses.isEmpty())
addresses = List.of(Inet4Address.getByName("0.0.0.0"));
return new StrolchNetworkInterface(ni.getName(), formatMacAddress(ni), addresses);
} catch (UnknownHostException e) {
throw new IllegalStateException("Failed to read information for device " + ni.getName(), e);
}
});
}
// Read all available device names
Pattern pattern = Pattern.compile("^ *(.*):");
List<String> kernelInterfaceLines;
try {
kernelInterfaceLines = readAllLines(Path.of("/proc/net/dev"));
} catch (IOException e) {
throw new IllegalStateException("Failed to read /proc/net/dev", e);
}
return kernelInterfaceLines.stream().map(line -> {
Matcher m = pattern.matcher(line);
if (m.find())
return m.group(1).trim();
return null;
}).filter(Objects::nonNull).filter(device -> {
if (device.startsWith("br-"))
return false;
if (device.startsWith("veth"))
return false;
if (device.startsWith("docker"))
return false;
return true;
}).map(device -> {
try {
String hwAddress = readString(Path.of("/sys/class/net/" + device + "/address")).trim();
File operStateFile = new File("/sys/class/net/" + device + "/operstate");
File carrierFile = new File("/sys/class/net/" + device + "/carrier");
boolean hasNoCarrier;
if (operStateFile.exists()) {
hasNoCarrier = operStateFile.exists() && readString(operStateFile.toPath()).trim().equals("down");
} else {
hasNoCarrier = readString(carrierFile.toPath()).trim().equals("0");
}
if (hasNoCarrier)
return new StrolchNetworkInterface(device, hwAddress, List.of(Inet4Address.getByName("0.0.0.0")));
NetworkInterface ni = NetworkInterface.getByName(device);
if (ni.isLoopback() || ni.isPointToPoint() || ni.isVirtual())
return null;
List<InetAddress> addresses = Collections.list(ni.getInetAddresses());
if (addresses.isEmpty())
addresses = List.of(Inet4Address.getByName("0.0.0.0"));
return new StrolchNetworkInterface(ni.getName(), hwAddress, addresses);
} catch (IOException e) {
throw new IllegalStateException("Failed to read information for device " + device, e);
}
}).filter(Objects::nonNull);
}
}

View File

@ -0,0 +1,12 @@
package li.strolch.utils.helper;
import java.net.InetAddress;
import java.util.List;
public record StrolchNetworkInterface(String name, String hwAddress, List<InetAddress> inetAddresses) {
public StrolchNetworkInterface(String name, String hwAddress, List<InetAddress> inetAddresses) {
this.name = name;
this.hwAddress = hwAddress;
this.inetAddresses = List.copyOf(inetAddresses);
}
}