diff --git a/chameleon-server/src/main/java/com/chameleonvision/network/LinuxNetworking.java b/chameleon-server/src/main/java/com/chameleonvision/network/LinuxNetworking.java index a2ddca8e3..4c5a8076c 100644 --- a/chameleon-server/src/main/java/com/chameleonvision/network/LinuxNetworking.java +++ b/chameleon-server/src/main/java/com/chameleonvision/network/LinuxNetworking.java @@ -1,11 +1,10 @@ package com.chameleonvision.network; -import io.javalin.core.util.FileUtil; import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.reflect.FieldUtils; import java.io.File; import java.io.IOException; +import java.net.InetAddress; import java.net.SocketException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -13,41 +12,42 @@ import java.util.Collections; import java.util.List; public class LinuxNetworking extends SysNetworking { + private static final String PATH = "/etc/dhcpcd.conf"; @Override public boolean setDHCP() { - File interfaces = new File("/etc/network/interfaces"); - try { - List lines = FileUtils.readLines(interfaces, StandardCharsets.UTF_8); - for (int i = 0; i < lines.size(); i++) { - String line = lines.get(i); - if (line.contains("iface " + networkInterface.name)) { - line = "iface " + networkInterface.name + "inet dhcp"; - lines.set(i, line); - List rLines = new ArrayList<>(); - for (var j = i; j < lines.size(); j++) { - String tmp = lines.get(j); - if (tmp.contains("address") || tmp.contains("netmask") || tmp.contains("gateway")) { - rLines.add(j); - } - if (tmp.contains("iface")) { - break; + File dhcpConf = new File(PATH); + if (dhcpConf.exists()) { + try { + List lines = FileUtils.readLines(dhcpConf, StandardCharsets.UTF_8); + for (int i = 0; i < lines.size(); i++) { + String line = lines.get(i); + if (line.contains("interface " + networkInterface.name)) { + lines.remove(i); + for (int j = i; j < lines.size(); j++) { + String subInterface = lines.get(j); + if (subInterface.contains("static ip_address") || subInterface.contains("static routers")) { + lines.remove(j); + j--; + } + if (subInterface.contains("interface")) { + break; + } } + FileUtils.writeLines(dhcpConf, lines); + return true; } - for (Integer rLine : rLines) { - lines.remove(rLine.intValue()); - } - FileUtils.writeLines(interfaces, lines); - Process p = Runtime.getRuntime().exec("systemctl restart network"); - p.waitFor(); - return true; } + } catch (IOException e) { + e.printStackTrace(); + return false; } - } catch (IOException | InterruptedException e) { - e.printStackTrace(); - } - return false; + } else { + System.err.println("dhcpcd5 is not installed cant set ip"); + return false; + } + return true; } @Override @@ -63,25 +63,18 @@ public class LinuxNetworking extends SysNetworking { } @Override - public boolean setStatic(String ipAddress, String netmask, String gateway, String broadcast) { - File interfaces = new File("/etc/network/interfaces"); + public boolean setStatic(String ipAddress, String netmask, String gateway) { + setDHCP(); + File dhcpConf = new File(PATH); try { - List lines = FileUtils.readLines(interfaces, StandardCharsets.UTF_8); - for (int i = 0; i < lines.size(); i++) { - String line = lines.get(i); - if (line.contains("iface " + networkInterface.name)) { - line = "iface " + networkInterface.name + "inet static"; - lines.set(i, line); - lines.add(i + 1, "address " + ipAddress); - lines.add(i + 2, "netmask " + netmask); - lines.add(i + 2, "gateway " + gateway); - FileUtils.writeLines(interfaces, lines); - Process p = Runtime.getRuntime().exec("systemctl restart network"); - p.waitFor(); - return true; - } - } - } catch (IOException | InterruptedException e) { + List lines = FileUtils.readLines(dhcpConf, StandardCharsets.UTF_8); + lines.add("interface " + networkInterface.name); + InetAddress iNetMask = InetAddress.getByName(netmask); + int prefix = NetmaskToCIDR.convertNetmaskToCIDR(iNetMask); + lines.add("static ip_address " + ipAddress + "/" + prefix); + lines.add("static routers " + gateway); + FileUtils.writeLines(dhcpConf, lines); + } catch (IOException e) { e.printStackTrace(); } return false; diff --git a/chameleon-server/src/main/java/com/chameleonvision/network/NetmaskToCIDR.java b/chameleon-server/src/main/java/com/chameleonvision/network/NetmaskToCIDR.java new file mode 100644 index 000000000..738e1321a --- /dev/null +++ b/chameleon-server/src/main/java/com/chameleonvision/network/NetmaskToCIDR.java @@ -0,0 +1,28 @@ +package com.chameleonvision.network; + +import java.net.InetAddress; + +public class NetmaskToCIDR { + public static int convertNetmaskToCIDR(InetAddress netmask){ + + byte[] netmaskBytes = netmask.getAddress(); + int cidr = 0; + boolean zero = false; + for(byte b : netmaskBytes){ + int mask = 0x80; + + for(int i = 0; i < 8; i++){ + int result = b & mask; + if(result == 0){ + zero = true; + }else if(zero){ + throw new IllegalArgumentException("Invalid netmask."); + } else { + cidr++; + } + mask >>>= 1; + } + } + return cidr; + } +} diff --git a/chameleon-server/src/main/java/com/chameleonvision/network/NetworkManager.java b/chameleon-server/src/main/java/com/chameleonvision/network/NetworkManager.java index d505199cd..1b1690882 100644 --- a/chameleon-server/src/main/java/com/chameleonvision/network/NetworkManager.java +++ b/chameleon-server/src/main/java/com/chameleonvision/network/NetworkManager.java @@ -9,44 +9,45 @@ import java.util.ArrayList; import java.util.List; public class NetworkManager { - private NetworkManager() {} + private NetworkManager() { + } - private static SysNetworking networking; - private static boolean isManaged = false; + private static SysNetworking networking; + private static boolean isManaged = false; - public static void initialize(boolean manage) { - isManaged = manage; - if (!isManaged) { - return; - } + public static void initialize(boolean manage) { + isManaged = manage; + if (!isManaged) { + return; + } - Platform platform = Platform.CurrentPlatform; + Platform platform = Platform.CurrentPlatform; - if (platform.isLinux()) { - networking = new LinuxNetworking(); - } else if (platform.isWindows()) { + if (platform.isLinux()) { + networking = new LinuxNetworking(); + } else if (platform.isWindows()) { // networking = new WindowsNetworking(); System.out.println("Windows networking is not yet supported. Running unmanaged."); return; - } + } - if (networking == null) { - throw new RuntimeException("Failed to detect platform!"); - } + if (networking == null) { + throw new RuntimeException("Failed to detect platform!"); + } - List interfaces = new ArrayList<>(); - List goodInterfaces = new ArrayList<>(); + List interfaces = new ArrayList<>(); + List goodInterfaces = new ArrayList<>(); - try { - interfaces = networking.getNetworkInterfaces(); - } catch (SocketException e) { - e.printStackTrace(); - } + try { + interfaces = networking.getNetworkInterfaces(); + } catch (SocketException e) { + e.printStackTrace(); + } var teamBytes = NetworkManager.GetTeamNumberIPBytes(ConfigManager.settings.teamNumber); if (interfaces.size() > 0) { - for (var inetface : interfaces) { + for (var inetface : interfaces) { for (var inetfaceAddr : inetface.getInterfaceAddresses()) { var rawAddr = inetfaceAddr.getAddress().getAddress(); if (rawAddr.length > 4) continue; @@ -54,74 +55,66 @@ public class NetworkManager { goodInterfaces.add(new NetworkInterface(inetface, inetfaceAddr)); } } - } + } - if (goodInterfaces.size() == 0) { - isManaged = false; - System.err.println("No valid network interfaces found! Staying unmanaged."); - return; - } + if (goodInterfaces.size() == 0) { + isManaged = false; + System.err.println("No valid network interfaces found! Staying unmanaged."); + return; + } - NetworkInterface botInterface = goodInterfaces.get(0); - networking.setNetworkInterface(botInterface); - } else { - isManaged = false; - System.err.println("No valid network interfaces found! Staying unmanaged."); - return; - } + NetworkInterface botInterface = goodInterfaces.get(0); + networking.setNetworkInterface(botInterface); + } else { + isManaged = false; + System.err.println("No valid network interfaces found! Staying unmanaged."); + return; + } - if(!loadFromGeneralSettings()) { - isManaged = false; - System.err.println("Failed to load network settings. Staying unmanaged!"); - } - } - - private static byte[] GetTeamNumberIPBytes(int teamNumber) { - return new byte[]{(byte) (teamNumber / 100), (byte) (teamNumber % 100)}; - } - - private static boolean loadFromGeneralSettings() { - if (!isManaged) { - return true; - } - - var genSettings = ConfigManager.settings; - boolean isStatic = genSettings.connectionType.equals(NetworkIPMode.STATIC); - - if (isStatic) { - var splitIPAddr = genSettings.ip.split("\\."); - splitIPAddr[3] = "255"; - var broadcast = String.join(".", splitIPAddr); - if (!setStatic(genSettings.ip, genSettings.netmask, genSettings.gateway, broadcast)) { - return false; - } - } else { - if (!setDHCP()) { - return false; - } - } - - return setHostname(genSettings.hostname); - } - - private static boolean setDHCP() { - if (!isManaged) { - return true; - } - return networking.setDHCP(); + if (!loadFromGeneralSettings()) { + isManaged = false; + System.err.println("Failed to load network settings. Staying unmanaged!"); + } } - private static boolean setStatic(String ipAddress, String netmask, String gateway, String broadcast) { - if (!isManaged) { - return true; - } - return networking.setStatic(ipAddress, netmask, gateway, broadcast); + private static byte[] GetTeamNumberIPBytes(int teamNumber) { + return new byte[]{(byte) (teamNumber / 100), (byte) (teamNumber % 100)}; + } + + private static boolean loadFromGeneralSettings() { + if (!isManaged) { + return true; + } + var genSettings = ConfigManager.settings; + return setHostname(genSettings.hostname); + } + + private static boolean setDHCP() { + if (!isManaged) { + return true; + } + return networking.setDHCP(); + } + + private static boolean setStatic(String ipAddress, String netmask, String gateway) { + if (!isManaged) { + return true; + } + return networking.setStatic(ipAddress, netmask, gateway); } private static boolean setHostname(String hostname) { - if (!isManaged) { - return true; - } - return networking.setHostname(hostname); + if (!isManaged) { + return true; + } + return networking.setHostname(hostname); + } + + public static boolean setNetwork(boolean isStatic, String ip, String netmask, String gateway) { + if (isStatic) { + return setStatic(ip, netmask, gateway); + } else { + return setDHCP(); + } } } diff --git a/chameleon-server/src/main/java/com/chameleonvision/network/SysNetworking.java b/chameleon-server/src/main/java/com/chameleonvision/network/SysNetworking.java index 63a609984..7073809fb 100644 --- a/chameleon-server/src/main/java/com/chameleonvision/network/SysNetworking.java +++ b/chameleon-server/src/main/java/com/chameleonvision/network/SysNetworking.java @@ -30,7 +30,7 @@ public abstract class SysNetworking { } public abstract boolean setDHCP(); public abstract boolean setHostname(String hostname); - public abstract boolean setStatic(String ipAddress, String netmask, String gateway, String broadcast); + public abstract boolean setStatic(String ipAddress, String netmask, String gateway); public abstract List getNetworkInterfaces() throws SocketException; } diff --git a/chameleon-server/src/main/java/com/chameleonvision/network/WindowsNetworking.java b/chameleon-server/src/main/java/com/chameleonvision/network/WindowsNetworking.java index d03da14e2..c6fdae74f 100644 --- a/chameleon-server/src/main/java/com/chameleonvision/network/WindowsNetworking.java +++ b/chameleon-server/src/main/java/com/chameleonvision/network/WindowsNetworking.java @@ -32,7 +32,7 @@ public class WindowsNetworking extends SysNetworking { } @Override - public boolean setStatic(String ipAddress, String netmask, String gateway, String broadcast) { + public boolean setStatic(String ipAddress, String netmask, String gateway) { return false; } diff --git a/chameleon-server/src/main/java/com/chameleonvision/web/RequestHandler.java b/chameleon-server/src/main/java/com/chameleonvision/web/RequestHandler.java index 55bc5e163..636c7b425 100644 --- a/chameleon-server/src/main/java/com/chameleonvision/web/RequestHandler.java +++ b/chameleon-server/src/main/java/com/chameleonvision/web/RequestHandler.java @@ -4,6 +4,7 @@ import com.chameleonvision.Exceptions.DuplicatedKeyException; import com.chameleonvision.Main; import com.chameleonvision.config.ConfigManager; import com.chameleonvision.network.NetworkIPMode; +import com.chameleonvision.network.NetworkManager; import com.chameleonvision.networktables.NetworkTablesManager; import com.chameleonvision.util.Helpers; import com.chameleonvision.util.Platform; @@ -52,7 +53,9 @@ public class RequestHandler { ConfigManager.settings.netmask = (String) map.get("netmask"); ConfigManager.settings.gateway = (String) map.get("gateway"); ConfigManager.settings.hostname = (String) map.get("hostname"); + boolean isStatic = ConfigManager.settings.connectionType.equals(NetworkIPMode.STATIC); ConfigManager.saveGeneralSettings(); + NetworkManager.setNetwork(isStatic, ConfigManager.settings.ip, ConfigManager.settings.netmask, ConfigManager.settings.gateway); SocketHandler.sendFullSettings(); ctx.status(200); } catch (JsonProcessingException e) {