/* * Copyright 2016 christopher.metter. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.uniwuerzburg.info3.ofcprobe.util; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import org.openflow.protocol.OFMatch; import org.openflow.util.U8; /** * Static Utilities Class. Containing helper Methods that are used over and over * again * * @author Christopher Metter(christopher.metter@informatik.uni-wuerzburg.de) * */ public class Util { /** * Parses a string containing hex numbers to a byte array. * * @param source source string * @return byte array from the parsed data */ public static byte[] toByteArray(String source) { String s = source.replaceAll(" |\n", ""); byte[] b = new byte[s.length() / 2]; if ((s.length() % 2) != 0) { throw new IllegalArgumentException( "need even number of hex double digits [" + s.length() + "]"); } for (int i = 0; i < s.length(); i += 2) { String q = s.substring(i, i + 2); b[i / 2] = (byte) Integer.parseInt(q, 16); } return b; } /** * Insert array in greater array * * @param array the target array * @param insert the source array * @param pos starting position of the target array * @return filled target array */ public static byte[] insertByteArray(byte[] array, byte[] insert, int pos) { if (pos + insert.length <= array.length) { for (int i = 0; i < insert.length; i++) { array[i + pos] = insert[i]; } } return array; } /** * Insert long value into byte array. * * @param buf the target array * @param value the long to insert into the array. * @param pos starting position of the target array. * @param cnt the number of bytes to insert. */ public static void insertLong(byte[] buf, long value, int pos, int cnt) { for (int i = 0; i < cnt; i++) { buf[pos + cnt - i - 1] = (byte) (value & 0xff); value >>= 8; } } /** * Get a part of a Byte[] * * @param data byte[] to read from * @param offset offset to start reading * @param cnt number of bytes to read * @return byte[]-part */ public static byte[] getBytes(byte[] data, int offset, int cnt) { byte[] output = new byte[cnt]; if (cnt <= data.length && offset + cnt <= data.length) { for (int i = 0; i < cnt; i++) { output[i] = data[offset + i]; } } return output; } /** * HelperMethod to Convert int to byte[] * * @param input in * @return byte[] */ public static byte[] toByte(int input, int count) { return ByteBuffer.allocate(count).putInt(input).array(); } /** * Convert a string of bytes to a hex string * * @param bytes * @return "0fcafedeadbeef" */ public static String asString(byte[] bytes) { int i; String ret = ""; String tmp; for (i = 0; i < bytes.length; i++) { if (i > 0) { ret += ""; } tmp = Integer.toHexString(U8.f(bytes[i])); if (tmp.length() == 1) { ret += "0"; } ret += tmp; } return ret; } /** * Accepts an IPv4 address of the form xxx.xxx.xxx.xxx, ie 192.168.0.1 and * returns the corresponding byte array. * * @param ipAddress The IP address in the form xx.xxx.xxx.xxx. * @return The IP address separated into bytes */ public static byte[] toIPv4AddressBytes(String ipAddress) { String[] octets = ipAddress.split("\\."); if (octets.length != 4) { throw new IllegalArgumentException("Specified IPv4 address must" + "contain 4 sets of numerical digits separated by periods"); } byte[] result = new byte[4]; for (int i = 0; i < 4; ++i) { result[i] = Integer.valueOf(octets[i]).byteValue(); } return result; } /** * Accepts an IPv4 address in a byte array and returns the corresponding * 32-bit integer value. * * @param ipAddress * @return */ public static int toIPv4Address(byte[] ipAddress) { int ip = 0; for (int i = 0; i < 4; i++) { int t = (ipAddress[i] & 0xff) << ((3 - i) * 8); ip |= t; } return ip; } /** * Accepts an IPv4 address and returns of string of the form xxx.xxx.xxx.xxx * ie 192.168.0.1 * * @param ipAddress * @return */ public static String fromIPv4Address(int ipAddress) { StringBuffer sb = new StringBuffer(); int result = 0; for (int i = 0; i < 4; ++i) { result = (ipAddress >> ((3 - i) * 8)) & 0xff; sb.append(Integer.valueOf(result).toString()); if (i != 3) { sb.append("."); } } return sb.toString(); } /** * Get IP String from byte[]-IP * * @param ipAddress the byte[]-IP * @return IP as String */ public static String fromIPvAddressBytes(byte[] ipAddress) { return Util.fromIPv4Address(Util.toIPv4Address(ipAddress)); } /** * Overriden equals Method for OFMatch * * @param matchOne first match * @param matchTwo second match * @return do they match? *schenkelklopf* */ public static boolean equalsFlow(OFMatch matchOne, OFMatch matchTwo) { int wildcardsOne = matchOne.getWildcards(); int wildcardsTwo = matchTwo.getWildcards(); // l1 if ((wildcardsOne & OFMatch.OFPFW_IN_PORT) == 0 && (wildcardsTwo & OFMatch.OFPFW_IN_PORT) == 0) { if (matchOne.getInputPort() != matchTwo.getInputPort()) { return false; } } return complementaryFlow(matchOne, matchTwo); } /** * equalsFlow stuff continued * * @param matchOne the first match * @param matchTwo the second match * @return do they match */ private static boolean complementaryFlow(OFMatch matchOne, OFMatch matchTwo) { int wildcards = matchOne.getWildcards(); int wildcardsTwo = matchTwo.getWildcards(); // l2 if ((wildcards & OFMatch.OFPFW_DL_DST) == 0 && (wildcardsTwo & OFMatch.OFPFW_DL_DST) == 0) { if (!Arrays.equals(matchOne.getDataLayerDestination(), matchTwo.getDataLayerDestination())) { return false; } } if ((wildcards & OFMatch.OFPFW_DL_SRC) == 0 && (wildcardsTwo & OFMatch.OFPFW_DL_SRC) == 0) { if (!Arrays.equals(matchOne.getDataLayerSource(), matchTwo.getDataLayerSource())) { return false; } } if ((wildcards & OFMatch.OFPFW_DL_TYPE) == 0 && (wildcardsTwo & OFMatch.OFPFW_DL_TYPE) == 0) { if (matchOne.getDataLayerType() != matchTwo.getDataLayerType()) { return false; } } if ((wildcards & OFMatch.OFPFW_DL_VLAN) == 0 && (wildcardsTwo & OFMatch.OFPFW_DL_VLAN) == 0) { if (matchOne.getDataLayerVirtualLan() != matchTwo .getDataLayerVirtualLan()) { return false; } } if ((wildcards & OFMatch.OFPFW_DL_VLAN_PCP) == 0 && (wildcardsTwo & OFMatch.OFPFW_DL_VLAN_PCP) == 0) { if (matchOne.getDataLayerVirtualLanPriorityCodePoint() != matchTwo .getDataLayerVirtualLanPriorityCodePoint()) { return false; } } // l3 if (matchOne.getNetworkDestinationMaskLen() > 0 && matchTwo.getNetworkDestinationMaskLen() > 0) { if (matchOne.getNetworkDestination() != matchTwo .getNetworkDestination()) { return false; } } if (matchOne.getNetworkSourceMaskLen() > 0 && matchTwo.getNetworkSourceMaskLen() > 0) { if (matchOne.getNetworkSource() != matchTwo.getNetworkSource()) { return false; } } if ((wildcards & OFMatch.OFPFW_NW_PROTO) == 0 && (wildcardsTwo & OFMatch.OFPFW_NW_PROTO) == 0) { if (matchOne.getNetworkProtocol() != matchTwo.getNetworkProtocol()) { return false; } } if ((wildcards & OFMatch.OFPFW_NW_TOS) == 0 && (wildcardsTwo & OFMatch.OFPFW_NW_TOS) == 0) { if (matchOne.getNetworkTypeOfService() != matchTwo .getNetworkTypeOfService()) { return false; } } // l4 if ((wildcards & OFMatch.OFPFW_TP_DST) == 0 && (wildcardsTwo & OFMatch.OFPFW_TP_DST) == 0) { if (matchOne.getTransportDestination() != matchTwo .getTransportDestination()) { return false; } } if ((wildcards & OFMatch.OFPFW_TP_SRC) == 0 && (wildcardsTwo & OFMatch.OFPFW_TP_SRC) == 0) { if (matchOne.getTransportSource() != matchTwo.getTransportSource()) { return false; } } return true; } /** * Computes the seconds between two Dates needed for Statistics Methods to * determine where to put processsed Packet * * @param start StartDate * @param now NowDate * @return Intevall */ public static int getIntervall(Date start, Date now) { long startL = start.getTime(); long nowL = now.getTime(); long diffi = nowL - startL; int inti = (int) Math.floor((diffi / 1000)); inti--; return inti; } /** * Ensure that a ArrayList has the provided size Needed for enhance * ArrayList.add(index, item) * * @param list the List * @param size the TargetSize */ public static void ensureSize(ArrayList<Integer> list, int size) { // Prevent excessive copying while we're adding list.ensureCapacity(size); while (list.size() < size) { list.add(0); } } public static void listSizeCheck(ArrayList<Integer> list, int intervall) { list.ensureCapacity(intervall + 1); while (list.size() < intervall + 1) { list.add(0); } } /** * See ensureSize * * @param list the List * @param size the TargetSize */ public static void ensureSizeDouble(ArrayList<Double> list, int size) { list.ensureCapacity(size); while (list.size() < size) { list.add(0.0); } } }