linux networking using dhcpcd5

This commit is contained in:
ori agranat
2020-02-24 23:52:19 +02:00
parent 676db036f8
commit 54a1ba1a5a
6 changed files with 151 additions and 134 deletions

View File

@@ -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<String> 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<Integer> 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<String> 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<String> 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<String> 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;

View File

@@ -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;
}
}

View File

@@ -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<java.net.NetworkInterface> interfaces = new ArrayList<>();
List<NetworkInterface> goodInterfaces = new ArrayList<>();
List<java.net.NetworkInterface> interfaces = new ArrayList<>();
List<NetworkInterface> 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();
}
}
}

View File

@@ -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<java.net.NetworkInterface> getNetworkInterfaces() throws SocketException;
}

View File

@@ -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;
}

View File

@@ -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) {