diff --git a/corefx/pom.xml b/corefx/pom.xml index 21839cc6..f5ce8b17 100644 --- a/corefx/pom.xml +++ b/corefx/pom.xml @@ -84,11 +84,6 @@ 1.18.0 provided - - commons-net - commons-net - 3.6 - com.jfoenix jfoenix @@ -114,6 +109,11 @@ guava 20.0 + + com.github.seancfoley + ipaddress + 5.0.2 + diff --git a/corefx/src/main/java/com/core/client/grpc/CoreGrpcClient.java b/corefx/src/main/java/com/core/client/grpc/CoreGrpcClient.java index 972c30be..dfe46f19 100644 --- a/corefx/src/main/java/com/core/client/grpc/CoreGrpcClient.java +++ b/corefx/src/main/java/com/core/client/grpc/CoreGrpcClient.java @@ -6,6 +6,8 @@ import com.core.client.rest.ServiceFile; import com.core.client.rest.WlanConfig; import com.core.data.*; import com.core.ui.dialogs.MobilityPlayerDialog; +import inet.ipaddr.IPAddress; +import inet.ipaddr.IPAddressString; import io.grpc.Context; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; @@ -123,6 +125,9 @@ public class CoreGrpcClient implements ICoreClient { private CoreProto.Interface interfaceToProto(CoreInterface coreInterface) { CoreProto.Interface.Builder builder = CoreProto.Interface.newBuilder(); + if (coreInterface.getId() != null) { + builder.setId(coreInterface.getId()); + } if (coreInterface.getName() != null) { builder.setName(coreInterface.getName()); } @@ -130,16 +135,16 @@ public class CoreGrpcClient implements ICoreClient { builder.setMac(coreInterface.getMac()); } if (coreInterface.getIp4() != null) { - builder.setIp4(coreInterface.getIp4()); + builder.setIp4(coreInterface.getIp4().toAddressString().getHostAddress().toString()); } - if (coreInterface.getIp4Mask() != null) { - builder.setIp4Mask(coreInterface.getIp4Mask()); + if (coreInterface.getIp4() != null) { + builder.setIp4Mask(coreInterface.getIp4().getPrefixLength()); } if (coreInterface.getIp6() != null) { - builder.setIp6(coreInterface.getIp6()); + builder.setIp6(coreInterface.getIp6().toAddressString().getHostAddress().toString()); } - if (coreInterface.getIp6Mask() != null) { - builder.setIp6Mask(Integer.parseInt(coreInterface.getIp6Mask())); + if (coreInterface.getIp6() != null) { + builder.setIp6Mask(coreInterface.getIp6().getPrefixLength()); } return builder.build(); } @@ -170,10 +175,12 @@ public class CoreGrpcClient implements ICoreClient { coreInterface.setId(protoInterface.getId()); coreInterface.setName(protoInterface.getName()); coreInterface.setMac(protoInterface.getMac()); - coreInterface.setIp4(protoInterface.getIp4()); - coreInterface.setIp4Mask(protoInterface.getIp4Mask()); - coreInterface.setIp6(protoInterface.getIp6()); - coreInterface.setIp6Mask(Integer.toString(protoInterface.getIp6Mask())); + String ip4String = String.format("%s/%s", protoInterface.getIp4(), protoInterface.getIp4Mask()); + IPAddress ip4 = new IPAddressString(ip4String).getAddress(); + coreInterface.setIp4(ip4); + String ip6String = String.format("%s/%s", protoInterface.getIp6(), protoInterface.getIp6Mask()); + IPAddress ip6 = new IPAddressString(ip6String).getAddress(); + coreInterface.setIp6(ip6); return coreInterface; } diff --git a/corefx/src/main/java/com/core/data/CoreInterface.java b/corefx/src/main/java/com/core/data/CoreInterface.java index f159f10e..200aeabd 100644 --- a/corefx/src/main/java/com/core/data/CoreInterface.java +++ b/corefx/src/main/java/com/core/data/CoreInterface.java @@ -1,6 +1,6 @@ package com.core.data; -import com.fasterxml.jackson.annotation.JsonProperty; +import inet.ipaddr.IPAddress; import lombok.Data; import lombok.NoArgsConstructor; @@ -10,10 +10,6 @@ public class CoreInterface { private Integer id; private String name; private String mac; - private String ip4; - @JsonProperty("ip4mask") - private Integer ip4Mask; - private String ip6; - @JsonProperty("ip6mask") - private String ip6Mask; + private IPAddress ip4; + private IPAddress ip6; } diff --git a/corefx/src/main/java/com/core/graph/CoreAddresses.java b/corefx/src/main/java/com/core/graph/CoreAddresses.java index 5db724b6..554145da 100644 --- a/corefx/src/main/java/com/core/graph/CoreAddresses.java +++ b/corefx/src/main/java/com/core/graph/CoreAddresses.java @@ -1,41 +1,87 @@ package com.core.graph; import com.core.data.CoreInterface; +import inet.ipaddr.IPAddress; +import inet.ipaddr.IPAddressString; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import java.util.Collection; +import java.util.Comparator; +import java.util.Set; public class CoreAddresses { private static final Logger logger = LogManager.getLogger(); - public static final int IP4_MASK = 24; - public static final int IP4_INDEX = (IP4_MASK / 8) - 1; + private IPAddress defaultSubnet = new IPAddressString("10.0.0.0/24").getAddress(); - private String ip4Base; - - public CoreAddresses(String ip4Base) { - this.ip4Base = ip4Base; + private IPAddress getMaxAddress(Set interfaces) { + return interfaces.stream() + .map(CoreInterface::getIp4) + .max(Comparator.comparingInt(x -> x.toIPv4().intValue())) + .orElseGet(() -> defaultSubnet); } - public int getSubnet(Collection nodeOneInterfaces, Collection nodeTwoInterfaces) { - int subOne = getMaxSubnet(nodeOneInterfaces); - int subTwo = getMaxSubnet(nodeTwoInterfaces); - logger.info("next subnet: {} - {}", subOne, subTwo); - return Math.max(subOne, subTwo) + 1; - } + public IPAddress getSubnet(Set nodeOneInterfaces, Set nodeTwoInterfaces, + boolean nodeOneIsNetwork, boolean nodeTwoIsNetwork) { + IPAddress nodeOneMax = getMaxAddress(nodeOneInterfaces); + IPAddress nodeTwoMax = getMaxAddress(nodeTwoInterfaces); - private int getMaxSubnet(Collection coreInterfaces) { - int sub = 0; - for (CoreInterface coreInterface : coreInterfaces) { - String[] values = coreInterface.getIp4().split("\\."); - int currentSub = Integer.parseInt(values[IP4_INDEX]); - logger.info("checking {} value {}", coreInterface.getIp4(), currentSub); - sub = Math.max(currentSub, sub); + logger.info("node one max: {}, node two max: {}", nodeOneMax, nodeTwoMax); + logger.info("max one compared to two: {} - {}", + nodeOneMax.toIPv4().intValue(), nodeTwoMax.toIPv4().intValue()); + boolean shouldBump; + boolean isDefault; + IPAddress subnet; + + if (nodeOneMax.toIPv4().intValue() > nodeTwoMax.toIPv4().intValue()) { + subnet = nodeOneMax; + isDefault = nodeOneMax == defaultSubnet; + shouldBump = !nodeOneIsNetwork && !isDefault; + } else { + subnet = nodeTwoMax; + isDefault = nodeTwoMax == defaultSubnet; + shouldBump = !nodeTwoIsNetwork && !isDefault; } - return sub; + + logger.info("found max address: {} - {}", isDefault, subnet); + if (!isDefault) { + subnet = subnet.toPrefixBlock(); + } + + if (shouldBump) { + logger.info("incrementing subnet for host to host"); + subnet = subnet.incrementBoundary(1); + } + + logger.info("found subnet: {}", subnet); + return subnet; } - public String getIp4Address(int sub, int id) { - return String.format("%s.%s.%s", ip4Base, sub, id); + public static void main(String... args) { + IPAddress addresses = new IPAddressString("10.0.100.1/24").getAddress(); + IPAddress addresses3 = new IPAddressString("10.0.0.2/24").getAddress(); + IPAddress addresses1 = new IPAddressString("10.0.1.0/24").getAddress(); + IPAddress addresses2 = new IPAddressString("10.0.2.0/24").getAddress(); + System.out.println(String.format("compare to greater: %s", addresses.compareTo(addresses3))); + System.out.println(String.format("compare to greater: %s", addresses3.compareTo(addresses1))); + System.out.println(String.format("compare to greater: %s", addresses.toInetAddress())); + + IPAddress address = addresses.increment(1); + IPAddress address1 = addresses1.increment(1); + IPAddress address2 = addresses2.increment(1); + System.out.println(String.format("divisions: %s", address.toPrefixBlock())); + System.out.println(String.format("divisions: %s", address1.toPrefixBlock())); + System.out.println(String.format("divisions: %s", address2.toPrefixBlock())); + System.out.println(String.format("compares: %s", address1.compareTo(address2))); + System.out.println(String.format("compares: %s", address1.compareTo(address))); + System.out.println(String.format("compares: %s", address2.getSection(2, 3))); + System.out.println(String.format("compares: %s", address2.getSegment(2))); + System.out.println(String.format("address: %s", address2)); + + IPAddress prefixBlock = address1.toPrefixBlock(); + System.out.println(String.format("prefix block: %s", prefixBlock)); + IPAddress update = new IPAddressString("0.0.1.0").getAddress(); + IPAddress nextAddress = prefixBlock.incrementBoundary(1); +// nextAddress.setPrefixLength(prefixBlock.getPrefixLength(), true); + System.out.println(String.format("prefix block update: %s", nextAddress)); } } diff --git a/corefx/src/main/java/com/core/graph/NetworkGraph.java b/corefx/src/main/java/com/core/graph/NetworkGraph.java index 7d55cdb2..2d9ec7af 100644 --- a/corefx/src/main/java/com/core/graph/NetworkGraph.java +++ b/corefx/src/main/java/com/core/graph/NetworkGraph.java @@ -20,9 +20,9 @@ import edu.uci.ics.jung.visualization.control.GraphMouseListener; import edu.uci.ics.jung.visualization.control.ModalGraphMouse; import edu.uci.ics.jung.visualization.decorators.EdgeShape; import edu.uci.ics.jung.visualization.renderers.Renderer; +import inet.ipaddr.IPAddress; import javafx.application.Platform; import lombok.Data; -import org.apache.commons.net.util.SubnetUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -32,7 +32,6 @@ import java.awt.event.MouseEvent; import java.awt.geom.Ellipse2D; import java.io.IOException; import java.util.*; -import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -50,8 +49,7 @@ public class NetworkGraph { private EditingModalGraphMouse graphMouse; private AnnotationControls annotationControls; - private SubnetUtils subnetUtils = new SubnetUtils("10.0.0.0/24"); - private CoreAddresses coreAddresses = new CoreAddresses("10.0"); + private CoreAddresses coreAddresses = new CoreAddresses(); private NodeType nodeType; private Map nodeMap = new ConcurrentHashMap<>(); private int vertexId = 1; @@ -287,40 +285,91 @@ public class NetworkGraph { private void handleEdgeAdded(GraphEvent.Edge edgeEvent) { CoreLink link = edgeEvent.getEdge(); - if (!link.isLoaded()) { - Pair endpoints = graph.getEndpoints(link); - - CoreNode nodeOne = endpoints.getFirst(); - CoreNode nodeTwo = endpoints.getSecond(); - - // create interfaces for nodes - int sub = coreAddresses.getSubnet( - getInterfaces(nodeOne), - getInterfaces(nodeTwo) - ); - - link.setNodeOne(nodeOne.getId()); - if (isNode(nodeOne)) { - int interfaceOneId = nextInterfaceId(nodeOne); - CoreInterface interfaceOne = createInterface(nodeOne, sub, interfaceOneId); - link.setInterfaceOne(interfaceOne); - } - - link.setNodeTwo(nodeTwo.getId()); - if (isNode(nodeTwo)) { - int interfaceTwoId = nextInterfaceId(nodeTwo); - CoreInterface interfaceTwo = createInterface(nodeTwo, sub, interfaceTwoId); - link.setInterfaceTwo(interfaceTwo); - } - - boolean isVisible = !checkForWirelessNode(nodeOne, nodeTwo); - link.setVisible(isVisible); - - logger.info("adding user created edge: {}", link); + if (link.isLoaded()) { + return; } + + Pair endpoints = graph.getEndpoints(link); + + CoreNode nodeOne = endpoints.getFirst(); + CoreNode nodeTwo = endpoints.getSecond(); + + // check if a node being linked is a network node + Set nodeOneInterfaces; + boolean nodeOneIsNetwork = false; + if (isNode(nodeOne)) { + nodeOneInterfaces = getNodeInterfaces(nodeOne); + } else { + nodeOneInterfaces = getNetworkInterfaces(nodeOne, new HashSet<>()); + nodeOneIsNetwork = true; + } + + Set nodeTwoInterfaces; + boolean nodeTwoIsNetwork = false; + if (isNode(nodeTwo)) { + nodeTwoInterfaces = getNodeInterfaces(nodeTwo); + } else { + nodeTwoInterfaces = getNetworkInterfaces(nodeTwo, new HashSet<>()); + nodeTwoIsNetwork = true; + } + + // create interfaces for nodes + IPAddress subnet = coreAddresses.getSubnet(nodeOneInterfaces, nodeTwoInterfaces, + nodeOneIsNetwork, nodeTwoIsNetwork); + + link.setNodeOne(nodeOne.getId()); + if (isNode(nodeOne)) { + int interfaceOneId = nextInterfaceId(nodeOne); + CoreInterface interfaceOne = createInterface(nodeOne, interfaceOneId, subnet); + link.setInterfaceOne(interfaceOne); + } + + link.setNodeTwo(nodeTwo.getId()); + if (isNode(nodeTwo)) { + int interfaceTwoId = nextInterfaceId(nodeTwo); + CoreInterface interfaceTwo = createInterface(nodeTwo, interfaceTwoId, subnet); + link.setInterfaceTwo(interfaceTwo); + } + + boolean isVisible = !checkForWirelessNode(nodeOne, nodeTwo); + link.setVisible(isVisible); + logger.info("adding user created edge: {}", link); } - public List getInterfaces(CoreNode node) { + public Set getNetworkInterfaces(CoreNode node, Set visited) { + Set interfaces = new HashSet<>(); + if (visited.contains(node)) { + return interfaces; + } + visited.add(node); + + logger.info("checking network node links: {}", node); + for (CoreLink link : graph.getIncidentEdges(node)) { + logger.info("checking link: {}", link); + if (link.getNodeOne() == null && link.getNodeTwo() == null) { + continue; + } + + // ignore oneself + CoreNode currentNode = getVertex(link.getNodeOne()); + CoreInterface currentInterface = link.getInterfaceOne(); + if (node.getId().equals(link.getNodeOne())) { + currentNode = getVertex(link.getNodeTwo()); + currentInterface = link.getInterfaceTwo(); + } + + if (isNode(currentNode)) { + interfaces.add(currentInterface); + } else { + Set nextInterfaces = getNetworkInterfaces(currentNode, visited); + interfaces.addAll(nextInterfaces); + } + } + + return interfaces; + } + + public Set getNodeInterfaces(CoreNode node) { return graph.getIncidentEdges(node).stream() .map(link -> { if (node.getId().equals(link.getNodeOne())) { @@ -330,7 +379,7 @@ public class NetworkGraph { } }) .filter(Objects::nonNull) - .collect(Collectors.toList()); + .collect(Collectors.toSet()); } private int nextInterfaceId(CoreNode node) { @@ -360,13 +409,13 @@ public class NetworkGraph { return node.getType() == NodeType.DEFAULT; } - private CoreInterface createInterface(CoreNode node, int sub, int interfaceId) { + private CoreInterface createInterface(CoreNode node, int interfaceId, IPAddress subnet) { CoreInterface coreInterface = new CoreInterface(); coreInterface.setId(interfaceId); coreInterface.setName(String.format("eth%s", interfaceId)); - String nodeOneIp4 = coreAddresses.getIp4Address(sub, node.getId()); - coreInterface.setIp4(nodeOneIp4); - coreInterface.setIp4Mask(CoreAddresses.IP4_MASK); + IPAddress address = subnet.increment(node.getId()); + coreInterface.setIp4(address); + coreInterface.setIp6(address.toIPv6()); return coreInterface; } diff --git a/corefx/src/main/java/com/core/ui/LinkDetails.java b/corefx/src/main/java/com/core/ui/LinkDetails.java index 5a0c78d0..b01c5e40 100644 --- a/corefx/src/main/java/com/core/ui/LinkDetails.java +++ b/corefx/src/main/java/com/core/ui/LinkDetails.java @@ -11,6 +11,7 @@ import com.core.ui.textfields.DoubleFilter; import com.core.utils.FxmlUtils; import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXTextField; +import inet.ipaddr.IPAddress; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.fxml.FXML; @@ -129,8 +130,8 @@ public class LinkDetails extends ScrollPane { if (coreInterface.getMac() != null) { addRow("MAC", coreInterface.getMac(), true); } - addIp4Address(coreInterface.getIp4(), coreInterface.getIp4Mask()); - addIp6Address(coreInterface.getIp6(), coreInterface.getIp6Mask()); + addIp4Address(coreInterface.getIp4()); + addIp6Address(coreInterface.getIp6()); } private void addRow(String labelText, String value, boolean disabled) { @@ -155,18 +156,18 @@ public class LinkDetails extends ScrollPane { return textField; } - private void addIp4Address(String ip, Integer mask) { + private void addIp4Address(IPAddress ip) { if (ip == null) { return; } - addRow("IP4", String.format("%s/%s", ip, mask), true); + addRow("IP4", ip.toString(), true); } - private void addIp6Address(String ip, String mask) { + private void addIp6Address(IPAddress ip) { if (ip == null) { return; } - addRow("IP6", String.format("%s/%s", ip, mask), true); + addRow("IP6", ip.toString(), true); } private void clear() { diff --git a/corefx/src/main/java/com/core/ui/NodeDetails.java b/corefx/src/main/java/com/core/ui/NodeDetails.java index c1e9751c..0fca8a95 100644 --- a/corefx/src/main/java/com/core/ui/NodeDetails.java +++ b/corefx/src/main/java/com/core/ui/NodeDetails.java @@ -10,6 +10,7 @@ import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXListView; import com.jfoenix.controls.JFXScrollPane; import com.jfoenix.controls.JFXTextField; +import inet.ipaddr.IPAddress; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.fxml.FXML; @@ -147,8 +148,8 @@ public class NodeDetails extends ScrollPane { if (coreInterface.getMac() != null) { addRow("MAC", coreInterface.getMac(), true); } - addIp4Address(coreInterface.getIp4(), coreInterface.getIp4Mask()); - addIp6Address(coreInterface.getIp6(), coreInterface.getIp6Mask()); + addIp4Address(coreInterface.getIp4()); + addIp6Address(coreInterface.getIp6()); } private void addRow(String labelText, String value, boolean disabled) { @@ -158,18 +159,18 @@ public class NodeDetails extends ScrollPane { gridPane.addRow(index++, label, textField); } - private void addIp4Address(String ip, Integer mask) { + private void addIp4Address(IPAddress ip) { if (ip == null) { return; } - addRow("IP4", String.format("%s/%s", ip, mask), true); + addRow("IP4", ip.toString(), true); } - private void addIp6Address(String ip, String mask) { + private void addIp6Address(IPAddress ip) { if (ip == null) { return; } - addRow("IP6", String.format("%s/%s", ip, mask), true); + addRow("IP6", ip.toString(), true); } private void clear() {