/utils/src/com/cloud/utils/net/MacAddress.java
Java | 383 lines | 264 code | 41 blank | 78 comment | 79 complexity | 01a00c1c594fb73961fd542949fb37cd MD5 | raw file
Possible License(s): Apache-2.0
- // Copyright 2012 Citrix Systems, Inc. Licensed under the
- // Apache License, Version 2.0 (the "License"); you may not use this
- // file except in compliance with the License. Citrix Systems, Inc.
- // reserves all rights not expressly granted by 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.
- //
- // Automatically generated by addcopyright.py at 04/03/2012
- package com.cloud.utils.net;
- import java.io.BufferedReader;
- import java.io.File;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.net.InetAddress;
- import java.net.UnknownHostException;
- import java.util.Formatter;
- import com.cloud.utils.NumbersUtil;
- /**
- * copied from the public domain utility from John Burkard.
- * @author <a href="mailto:jb@eaio.com">Johann Burkard</a>
- * @version 2.1.3
- **/
- public class MacAddress {
- private long _addr = 0;
- protected MacAddress() {
- }
- public MacAddress(long addr) {
- _addr = addr;
- }
- public long toLong() {
- return _addr;
- }
- public byte[] toByteArray() {
- byte[] bytes = new byte[6];
- bytes[0] = (byte)((_addr >> 40) & 0xff);
- bytes[1] = (byte)((_addr >> 32) & 0xff);
- bytes[2] = (byte)((_addr >> 24) & 0xff);
- bytes[3] = (byte)((_addr >> 16) & 0xff);
- bytes[4] = (byte)((_addr >> 8) & 0xff);
- bytes[5] = (byte)((_addr >> 0) & 0xff);
- return bytes;
- }
- public String toString(String separator) {
- StringBuilder buff = new StringBuilder();
- Formatter formatter = new Formatter(buff);
- formatter.format("%02x%s%02x%s%02x%s%02x%s%02x%s%02x",
- _addr >> 40 & 0xff, separator,
- _addr >> 32 & 0xff, separator,
- _addr >> 24 & 0xff, separator,
- _addr >> 16 & 0xff, separator,
- _addr >> 8 & 0xff, separator,
- _addr & 0xff);
- return buff.toString();
-
- /*
-
- String str = Long.toHexString(_addr);
- for (int i = str.length() - 1; i >= 0; i--) {
- buff.append(str.charAt(i));
- if (separator != null && (str.length() - i) % 2 == 0) {
- buff.append(separator);
- }
- }
- return buff.reverse().toString();
- */
- }
- @Override
- public String toString() {
- return toString(":");
- }
- private static MacAddress s_address;
- static {
- String macAddress = null;
- Process p = null;
- BufferedReader in = null;
- try {
- String osname = System.getProperty("os.name");
- if (osname.startsWith("Windows")) {
- p = Runtime.getRuntime().exec(new String[] { "ipconfig", "/all"}, null);
- } else if (osname.startsWith("Solaris") || osname.startsWith("SunOS")) {
- // Solaris code must appear before the generic code
- String hostName = MacAddress.getFirstLineOfCommand(new String[] { "uname",
- "-n"});
- if (hostName != null) {
- p = Runtime.getRuntime().exec(new String[] { "/usr/sbin/arp", hostName}, null);
- }
- } else if (new File("/usr/sbin/lanscan").exists()) {
- p = Runtime.getRuntime().exec(new String[] { "/usr/sbin/lanscan"}, null);
- } else if (new File("/sbin/ifconfig").exists()) {
- p = Runtime.getRuntime().exec(new String[] { "/sbin/ifconfig", "-a"}, null);
- }
- if (p != null) {
- in = new BufferedReader(new InputStreamReader(p.getInputStream()), 128);
- String l = null;
- while ((l = in.readLine()) != null) {
- macAddress = MacAddress.parse(l);
- if (macAddress != null && MacAddress.parseShort(macAddress) != 0xff)
- break;
- }
- }
- } catch (SecurityException ex) {
- } catch (IOException ex) {
- } finally {
- if (p != null) {
- if (in != null) {
- try {
- in.close();
- } catch (IOException ex) {
- }
- }
- try {
- p.getErrorStream().close();
- } catch (IOException ex) {
- }
- try {
- p.getOutputStream().close();
- } catch (IOException ex) {
- }
- p.destroy();
- }
- }
- long clockSeqAndNode = 0;
- if (macAddress != null) {
- if (macAddress.indexOf(':') != -1) {
- clockSeqAndNode |= MacAddress.parseLong(macAddress);
- } else if (macAddress.startsWith("0x")) {
- clockSeqAndNode |= MacAddress.parseLong(macAddress.substring(2));
- }
- } else {
- try {
- byte[] local = InetAddress.getLocalHost().getAddress();
- clockSeqAndNode |= (local[0] << 24) & 0xFF000000L;
- clockSeqAndNode |= (local[1] << 16) & 0xFF0000;
- clockSeqAndNode |= (local[2] << 8) & 0xFF00;
- clockSeqAndNode |= local[3] & 0xFF;
- } catch (UnknownHostException ex) {
- clockSeqAndNode |= (long) (Math.random() * 0x7FFFFFFF);
- }
- }
-
- s_address = new MacAddress(clockSeqAndNode);
- }
- public static MacAddress getMacAddress() {
- return s_address;
- }
- private static String getFirstLineOfCommand(String[] commands) throws IOException {
- Process p = null;
- BufferedReader reader = null;
- try {
- p = Runtime.getRuntime().exec(commands);
- reader = new BufferedReader(new InputStreamReader(p.getInputStream()), 128);
- return reader.readLine();
- } finally {
- if (p != null) {
- if (reader != null) {
- try {
- reader.close();
- } catch (IOException ex) {
- }
- }
- try {
- p.getErrorStream().close();
- } catch (IOException ex) {
- }
- try {
- p.getOutputStream().close();
- } catch (IOException ex) {
- }
- p.destroy();
- }
- }
- }
- /**
- * The MAC address parser attempts to find the following patterns:
- * <ul>
- * <li>.{1,2}:.{1,2}:.{1,2}:.{1,2}:.{1,2}:.{1,2}</li>
- * <li>.{1,2}-.{1,2}-.{1,2}-.{1,2}-.{1,2}-.{1,2}</li>
- * </ul>
- *
- * This is copied from the author below. The author encouraged copying
- * it.
- *
- */
- static String parse(String in) {
- // lanscan
- int hexStart = in.indexOf("0x");
- if (hexStart != -1) {
- int hexEnd = in.indexOf(' ', hexStart);
- if (hexEnd != -1) {
- return in.substring(hexStart, hexEnd);
- }
- }
- int octets = 0;
- int lastIndex, old, end;
- if (in.indexOf('-') > -1) {
- in = in.replace('-', ':');
- }
- lastIndex = in.lastIndexOf(':');
- if (lastIndex > in.length() - 2) return null;
- end = Math.min(in.length(), lastIndex + 3);
- ++octets;
- old = lastIndex;
- while (octets != 5 && lastIndex != -1 && lastIndex > 1) {
- lastIndex = in.lastIndexOf(':', --lastIndex);
- if (old - lastIndex == 3 || old - lastIndex == 2) {
- ++octets;
- old = lastIndex;
- }
- }
- if (octets == 5 && lastIndex > 1) {
- return in.substring(lastIndex - 2, end).trim();
- }
- return null;
- }
- public static void main(String[] args) {
- MacAddress addr = MacAddress.getMacAddress();
- System.out.println("addr in integer is " + addr.toLong());
- System.out.println("addr in bytes is " + NumbersUtil.bytesToString(addr.toByteArray(), 0, addr.toByteArray().length));
- System.out.println("addr in char is " + addr.toString(":"));
- }
- private static final char[] DIGITS = { '0', '1', '2', '3', '4', '5', '6',
- '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
- /**
- * Parses a <code>long</code> from a hex encoded number. This method will skip
- * all characters that are not 0-9 and a-f (the String is lower cased first).
- * Returns 0 if the String does not contain any interesting characters.
- *
- * @param s the String to extract a <code>long</code> from, may not be <code>null</code>
- * @return a <code>long</code>
- * @throws NullPointerException if the String is <code>null</code>
- */
- public static long parseLong(String s) throws NullPointerException {
- s = s.toLowerCase();
- long out = 0;
- byte shifts = 0;
- char c;
- for (int i = 0; i < s.length() && shifts < 16; i++) {
- c = s.charAt(i);
- if ((c > 47) && (c < 58)) {
- out <<= 4;
- ++shifts;
- out |= c - 48;
- }
- else if ((c > 96) && (c < 103)) {
- ++shifts;
- out <<= 4;
- out |= c - 87;
- }
- }
- return out;
- }
- /**
- * Parses an <code>int</code> from a hex encoded number. This method will skip
- * all characters that are not 0-9 and a-f (the String is lower cased first).
- * Returns 0 if the String does not contain any interesting characters.
- *
- * @param s the String to extract an <code>int</code> from, may not be <code>null</code>
- * @return an <code>int</code>
- * @throws NullPointerException if the String is <code>null</code>
- */
- public static int parseInt(String s) throws NullPointerException {
- s = s.toLowerCase();
- int out = 0;
- byte shifts = 0;
- char c;
- for (int i = 0; i < s.length() && shifts < 8; i++) {
- c = s.charAt(i);
- if ((c > 47) && (c < 58)) {
- out <<= 4;
- ++shifts;
- out |= c - 48;
- }
- else if ((c > 96) && (c < 103)) {
- ++shifts;
- out <<= 4;
- out |= c - 87;
- }
- }
- return out;
- }
- /**
- * Parses a <code>short</code> from a hex encoded number. This method will skip
- * all characters that are not 0-9 and a-f (the String is lower cased first).
- * Returns 0 if the String does not contain any interesting characters.
- *
- * @param s the String to extract a <code>short</code> from, may not be <code>null</code>
- * @return a <code>short</code>
- * @throws NullPointerException if the String is <code>null</code>
- */
- public static short parseShort(String s) throws NullPointerException {
- s = s.toLowerCase();
- short out = 0;
- byte shifts = 0;
- char c;
- for (int i = 0; i < s.length() && shifts < 4; i++) {
- c = s.charAt(i);
- if ((c > 47) && (c < 58)) {
- out <<= 4;
- ++shifts;
- out |= c - 48;
- }
- else if ((c > 96) && (c < 103)) {
- ++shifts;
- out <<= 4;
- out |= c - 87;
- }
- }
- return out;
- }
- /**
- * Parses a <code>byte</code> from a hex encoded number. This method will skip
- * all characters that are not 0-9 and a-f (the String is lower cased first).
- * Returns 0 if the String does not contain any interesting characters.
- *
- * @param s the String to extract a <code>byte</code> from, may not be <code>null</code>
- * @return a <code>byte</code>
- * @throws NullPointerException if the String is <code>null</code>
- */
- public static byte parseByte(String s) throws NullPointerException {
- s = s.toLowerCase();
- byte out = 0;
- byte shifts = 0;
- char c;
- for (int i = 0; i < s.length() && shifts < 2; i++) {
- c = s.charAt(i);
- if ((c > 47) && (c < 58)) {
- out <<= 4;
- ++shifts;
- out |= c - 48;
- }
- else if ((c > 96) && (c < 103)) {
- ++shifts;
- out <<= 4;
- out |= c - 87;
- }
- }
- return out;
- }
- }