X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fsal%2Fapi%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Futils%2FNetUtils.java;h=6b303f09f11955a053f7bcf740bf9f647b5df2ce;hp=8e76c3fc60d81e35b552bd8bb54edf73d997bf6e;hb=c1d6c147a5fdd6b18cf9f00e1bb7855020f2361f;hpb=b8bb7db7c6133e00046e85ead70426eb1e05184d diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/NetUtils.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/NetUtils.java index 8e76c3fc60..6b303f09f1 100644 --- a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/NetUtils.java +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/NetUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2013-2014 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, @@ -8,9 +8,11 @@ package org.opendaylight.controller.sal.utils; +import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.UnknownHostException; +import java.util.Arrays; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -28,6 +30,21 @@ public abstract class NetUtils { */ public static final int NumBitsInAByte = 8; + /** + * Constant holding the number of bytes in MAC Address + */ + public static final int MACAddrLengthInBytes = 6; + + /** + * Constant holding the number of words in MAC Address + */ + public static final int MACAddrLengthInWords = 3; + + /** + * Constant holding the broadcast MAC address + */ + private static final byte[] BroadcastMACAddr = {-1, -1, -1, -1, -1, -1}; + /** * Converts a 4 bytes array into an integer number * @@ -43,20 +60,46 @@ public abstract class NetUtils { } /** - * Converts a long to 6 bytes array for mac addresses - * @param addr - * @return + * Converts a 6 bytes array into a long number MAC addresses. + * + * @param ba + * The 6 bytes long byte array. + * @return The long number. + * Zero is returned if {@code ba} is {@code null} or + * the length of it is not six. */ + public static long byteArray6ToLong(byte[] ba) { + if (ba == null || ba.length != MACAddrLengthInBytes) { + return 0L; + } + long num = 0L; + int i = 0; + do { + num <<= NumBitsInAByte; + num |= 0xff & ba[i]; + i++; + } while (i < MACAddrLengthInBytes); + return num; + } + /** + * Converts a long number to a 6 bytes array for MAC addresses. + * + * @param addr + * The long number. + * @return The byte array. + */ public static byte[] longToByteArray6(long addr){ - byte[] mac = new byte[6]; - for(int i = 0; i < 6; i++){ - mac[i] = (byte) (addr >> (i*8)); - } + byte[] mac = new byte[MACAddrLengthInBytes]; + int i = MACAddrLengthInBytes - 1; + do { + mac[i] = (byte) addr; + addr >>>= NumBitsInAByte; + i--; + } while (i >= 0); return mac; } - /** * Converts an integer number into a 4 bytes array * @@ -129,46 +172,44 @@ public abstract class NetUtils { } /** - * Returns the number of contiguous bits belonging to the subnet, that have - * to be masked out Example: A prefix network byte mask of ff.ff.ff.00 will - * give a subnet mask length of 8, while ff.00.00.00 will return a subnet - * mask length of 24. If the passed prefixMask object is null, 0 is returned + * Returns the prefix size in bits of the specified subnet mask. Example: + * For the subnet mask ff.ff.ff.e0 it returns 25 while for ff.00.00.00 it + * returns 8. If the passed subnetMask array is null, 0 is returned. * - * @param prefixMask - * the prefix mask as byte array - * @return the length of the prefix network mask + * @param subnetMask + * the subnet mask as byte array + * @return the prefix length as number of bits */ - public static int getSubnetMaskLength(byte[] prefixMask) { + public static int getSubnetMaskLength(byte[] subnetMask) { int maskLength = 0; - if (prefixMask != null) { - // Create bit mask - int intMask = 0; - int numBytes = prefixMask.length; - for (int i = 0; i < numBytes; i++) { - intMask |= (prefixMask[i] & 0xff) << (8 * (numBytes - 1 - i)); + if (subnetMask != null && (subnetMask.length == 4 || subnetMask.length == 16)) { + int index = 0; + while (index < subnetMask.length && subnetMask[index] == (byte) 0xFF) { + maskLength += NetUtils.NumBitsInAByte; + index++; } - - int bit = 1; - while (((intMask & bit) == 0) && (maskLength <= (numBytes * 8))) { - maskLength += 1; - bit = bit << 1; + if (index != subnetMask.length) { + int bits = NetUtils.NumBitsInAByte - 1; + while (bits >= 0 && (subnetMask[index] & 1 << bits) != 0) { + bits--; + maskLength++; + } } } return maskLength; } /** - * Returns the number of contiguous bits belonging to the subnet, that have - * to be masked out Example: A prefix network byte mask of ff.ff.ff.00 will - * give a subnet mask length of 8, while ff.00.00.00 will return a subnet - * mask length of 24 If the passed prefixMask object is null, 0 is returned + * Returns the prefix size in bits of the specified subnet mask. Example: + * For the subnet mask 255.255.255.128 it returns 25 while for 255.0.0.0 it + * returns 8. If the passed subnetMask object is null, 0 is returned * - * @param prefixMask - * the prefix mask as InetAddress - * @return the length of the prefix network mask + * @param subnetMask + * the subnet mask as InetAddress + * @return the prefix length as number of bits */ - public static int getSubnetMaskLength(InetAddress prefixMask) { - return (prefixMask == null) ? 0 : NetUtils.getSubnetMaskLength(prefixMask.getAddress()); + public static int getSubnetMaskLength(InetAddress subnetMask) { + return subnetMask == null ? 0 : NetUtils.getSubnetMaskLength(subnetMask.getAddress()); } /** @@ -206,11 +247,18 @@ public abstract class NetUtils { * Checks if the test address and mask conflicts with the filter address and * mask * - * For example: testAddress: 172.28.2.23 testMask: 255.255.255.0 - * filtAddress: 172.28.1.10 testMask: 255.255.255.0 conflict + * For example: + * testAddress: 172.28.2.23 + * testMask: 255.255.255.0 + * filterAddress: 172.28.1.10 + * testMask: 255.255.255.0 + * do conflict * - * testAddress: 172.28.2.23 testMask: 255.255.255.0 filtAddress: 172.28.1.10 - * testMask: 255.255.0.0 do not conflict + * testAddress: 172.28.2.23 + * testMask: 255.255.255.0 + * filterAddress: 172.28.1.10 + * testMask: 255.255.0.0 + * do not conflict * * Null parameters are permitted * @@ -232,20 +280,19 @@ public abstract class NetUtils { return false; } - int testMaskLen = (testMask != null) ? NetUtils.getSubnetMaskLength(testMask.getAddress()) : 0; - int filterMaskLen = (filterMask != null) ? NetUtils.getSubnetMaskLength(filterMask.getAddress()) : 0; - - int testPrefixLen = (testAddress instanceof Inet6Address) ? (128 - testMaskLen) : (32 - testMaskLen); - int filterPrefixLen = (filterAddress instanceof Inet6Address) ? (128 - filterMaskLen) : (32 - filterMaskLen); + int testMaskLen = (testMask == null) ? ((testAddress instanceof Inet4Address) ? 32 : 128) : NetUtils + .getSubnetMaskLength(testMask); + int filterMaskLen = (filterMask == null) ? ((testAddress instanceof Inet4Address) ? 32 : 128) : NetUtils + .getSubnetMaskLength(filterMask); // Mask length check. Test mask has to be more specific than filter one - if (testPrefixLen < filterPrefixLen) { + if (testMaskLen < filterMaskLen) { return true; } // Subnet Prefix on filter mask length must be the same - InetAddress prefix1 = getSubnetPrefix(testAddress, filterPrefixLen); - InetAddress prefix2 = getSubnetPrefix(filterAddress, filterPrefixLen); + InetAddress prefix1 = getSubnetPrefix(testAddress, filterMaskLen); + InetAddress prefix2 = getSubnetPrefix(filterAddress, filterMaskLen); return (!prefix1.equals(prefix2)); } @@ -265,6 +312,54 @@ public abstract class NetUtils { return true; } + /** + * Returns true if the MAC address is the broadcast MAC address and false + * otherwise. + * + * @param MACAddress + * @return + */ + public static boolean isBroadcastMACAddr(byte[] MACAddress) { + if (MACAddress.length == MACAddrLengthInBytes) { + for (int i = 0; i < 6; i++) { + if (MACAddress[i] != BroadcastMACAddr[i]) { + return false; + } + } + return true; + } + + return false; + } + /** + * Returns true if the MAC address is a unicast MAC address and false + * otherwise. + * + * @param MACAddress + * @return + */ + public static boolean isUnicastMACAddr(byte[] MACAddress) { + if (MACAddress.length == MACAddrLengthInBytes) { + return (MACAddress[0] & 1) == 0; + } + return false; + } + + /** + * Returns true if the MAC address is a multicast MAC address and false + * otherwise. Note that this explicitly returns false for the broadcast MAC + * address. + * + * @param MACAddress + * @return + */ + public static boolean isMulticastMACAddr(byte[] MACAddress) { + if (MACAddress.length == MACAddrLengthInBytes && !isBroadcastMACAddr(MACAddress)) { + return (MACAddress[0] & 1) != 0; + } + return false; + } + /** * Returns true if the passed InetAddress contains all zero * @@ -375,7 +470,7 @@ public abstract class NetUtils { /* * Following utilities are useful when you need to compare or bit shift java - * primitive type variable which are inerently signed + * primitive type variable which are inherently signed */ /** * Returns the unsigned value of the passed byte variable @@ -385,7 +480,7 @@ public abstract class NetUtils { * @return the int variable containing the unsigned byte value */ public static int getUnsignedByte(byte b) { - return (b > 0) ? (int) b : (b & 0x7F | 0x80); + return b & 0xFF; } /** @@ -396,7 +491,7 @@ public abstract class NetUtils { * @return the int variable containing the unsigned short value */ public static int getUnsignedShort(short s) { - return (s > 0) ? (int) s : (s & 0x7FFF | 0x8000); + return s & 0xFFFF; } /** @@ -414,4 +509,13 @@ public abstract class NetUtils { return null; } } + + /** + * Returns Broadcast MAC Address + * + * @return the byte array containing broadcast mac address + */ + public static byte[] getBroadcastMACAddr() { + return Arrays.copyOf(BroadcastMACAddr, BroadcastMACAddr.length); + } }