PageRenderTime 52ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/utils/src/com/cloud/utils/net/MacAddress.java

https://github.com/jlk/CloudStack
Java | 383 lines | 264 code | 41 blank | 78 comment | 79 complexity | 01a00c1c594fb73961fd542949fb37cd MD5 | raw file
Possible License(s): Apache-2.0
  1. // Copyright 2012 Citrix Systems, Inc. Licensed under the
  2. // Apache License, Version 2.0 (the "License"); you may not use this
  3. // file except in compliance with the License. Citrix Systems, Inc.
  4. // reserves all rights not expressly granted by the License.
  5. // You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
  6. // Unless required by applicable law or agreed to in writing, software
  7. // distributed under the License is distributed on an "AS IS" BASIS,
  8. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9. // See the License for the specific language governing permissions and
  10. // limitations under the License.
  11. //
  12. // Automatically generated by addcopyright.py at 04/03/2012
  13. package com.cloud.utils.net;
  14. import java.io.BufferedReader;
  15. import java.io.File;
  16. import java.io.IOException;
  17. import java.io.InputStreamReader;
  18. import java.net.InetAddress;
  19. import java.net.UnknownHostException;
  20. import java.util.Formatter;
  21. import com.cloud.utils.NumbersUtil;
  22. /**
  23. * copied from the public domain utility from John Burkard.
  24. * @author <a href="mailto:jb@eaio.com">Johann Burkard</a>
  25. * @version 2.1.3
  26. **/
  27. public class MacAddress {
  28. private long _addr = 0;
  29. protected MacAddress() {
  30. }
  31. public MacAddress(long addr) {
  32. _addr = addr;
  33. }
  34. public long toLong() {
  35. return _addr;
  36. }
  37. public byte[] toByteArray() {
  38. byte[] bytes = new byte[6];
  39. bytes[0] = (byte)((_addr >> 40) & 0xff);
  40. bytes[1] = (byte)((_addr >> 32) & 0xff);
  41. bytes[2] = (byte)((_addr >> 24) & 0xff);
  42. bytes[3] = (byte)((_addr >> 16) & 0xff);
  43. bytes[4] = (byte)((_addr >> 8) & 0xff);
  44. bytes[5] = (byte)((_addr >> 0) & 0xff);
  45. return bytes;
  46. }
  47. public String toString(String separator) {
  48. StringBuilder buff = new StringBuilder();
  49. Formatter formatter = new Formatter(buff);
  50. formatter.format("%02x%s%02x%s%02x%s%02x%s%02x%s%02x",
  51. _addr >> 40 & 0xff, separator,
  52. _addr >> 32 & 0xff, separator,
  53. _addr >> 24 & 0xff, separator,
  54. _addr >> 16 & 0xff, separator,
  55. _addr >> 8 & 0xff, separator,
  56. _addr & 0xff);
  57. return buff.toString();
  58. /*
  59. String str = Long.toHexString(_addr);
  60. for (int i = str.length() - 1; i >= 0; i--) {
  61. buff.append(str.charAt(i));
  62. if (separator != null && (str.length() - i) % 2 == 0) {
  63. buff.append(separator);
  64. }
  65. }
  66. return buff.reverse().toString();
  67. */
  68. }
  69. @Override
  70. public String toString() {
  71. return toString(":");
  72. }
  73. private static MacAddress s_address;
  74. static {
  75. String macAddress = null;
  76. Process p = null;
  77. BufferedReader in = null;
  78. try {
  79. String osname = System.getProperty("os.name");
  80. if (osname.startsWith("Windows")) {
  81. p = Runtime.getRuntime().exec(new String[] { "ipconfig", "/all"}, null);
  82. } else if (osname.startsWith("Solaris") || osname.startsWith("SunOS")) {
  83. // Solaris code must appear before the generic code
  84. String hostName = MacAddress.getFirstLineOfCommand(new String[] { "uname",
  85. "-n"});
  86. if (hostName != null) {
  87. p = Runtime.getRuntime().exec(new String[] { "/usr/sbin/arp", hostName}, null);
  88. }
  89. } else if (new File("/usr/sbin/lanscan").exists()) {
  90. p = Runtime.getRuntime().exec(new String[] { "/usr/sbin/lanscan"}, null);
  91. } else if (new File("/sbin/ifconfig").exists()) {
  92. p = Runtime.getRuntime().exec(new String[] { "/sbin/ifconfig", "-a"}, null);
  93. }
  94. if (p != null) {
  95. in = new BufferedReader(new InputStreamReader(p.getInputStream()), 128);
  96. String l = null;
  97. while ((l = in.readLine()) != null) {
  98. macAddress = MacAddress.parse(l);
  99. if (macAddress != null && MacAddress.parseShort(macAddress) != 0xff)
  100. break;
  101. }
  102. }
  103. } catch (SecurityException ex) {
  104. } catch (IOException ex) {
  105. } finally {
  106. if (p != null) {
  107. if (in != null) {
  108. try {
  109. in.close();
  110. } catch (IOException ex) {
  111. }
  112. }
  113. try {
  114. p.getErrorStream().close();
  115. } catch (IOException ex) {
  116. }
  117. try {
  118. p.getOutputStream().close();
  119. } catch (IOException ex) {
  120. }
  121. p.destroy();
  122. }
  123. }
  124. long clockSeqAndNode = 0;
  125. if (macAddress != null) {
  126. if (macAddress.indexOf(':') != -1) {
  127. clockSeqAndNode |= MacAddress.parseLong(macAddress);
  128. } else if (macAddress.startsWith("0x")) {
  129. clockSeqAndNode |= MacAddress.parseLong(macAddress.substring(2));
  130. }
  131. } else {
  132. try {
  133. byte[] local = InetAddress.getLocalHost().getAddress();
  134. clockSeqAndNode |= (local[0] << 24) & 0xFF000000L;
  135. clockSeqAndNode |= (local[1] << 16) & 0xFF0000;
  136. clockSeqAndNode |= (local[2] << 8) & 0xFF00;
  137. clockSeqAndNode |= local[3] & 0xFF;
  138. } catch (UnknownHostException ex) {
  139. clockSeqAndNode |= (long) (Math.random() * 0x7FFFFFFF);
  140. }
  141. }
  142. s_address = new MacAddress(clockSeqAndNode);
  143. }
  144. public static MacAddress getMacAddress() {
  145. return s_address;
  146. }
  147. private static String getFirstLineOfCommand(String[] commands) throws IOException {
  148. Process p = null;
  149. BufferedReader reader = null;
  150. try {
  151. p = Runtime.getRuntime().exec(commands);
  152. reader = new BufferedReader(new InputStreamReader(p.getInputStream()), 128);
  153. return reader.readLine();
  154. } finally {
  155. if (p != null) {
  156. if (reader != null) {
  157. try {
  158. reader.close();
  159. } catch (IOException ex) {
  160. }
  161. }
  162. try {
  163. p.getErrorStream().close();
  164. } catch (IOException ex) {
  165. }
  166. try {
  167. p.getOutputStream().close();
  168. } catch (IOException ex) {
  169. }
  170. p.destroy();
  171. }
  172. }
  173. }
  174. /**
  175. * The MAC address parser attempts to find the following patterns:
  176. * <ul>
  177. * <li>.{1,2}:.{1,2}:.{1,2}:.{1,2}:.{1,2}:.{1,2}</li>
  178. * <li>.{1,2}-.{1,2}-.{1,2}-.{1,2}-.{1,2}-.{1,2}</li>
  179. * </ul>
  180. *
  181. * This is copied from the author below. The author encouraged copying
  182. * it.
  183. *
  184. */
  185. static String parse(String in) {
  186. // lanscan
  187. int hexStart = in.indexOf("0x");
  188. if (hexStart != -1) {
  189. int hexEnd = in.indexOf(' ', hexStart);
  190. if (hexEnd != -1) {
  191. return in.substring(hexStart, hexEnd);
  192. }
  193. }
  194. int octets = 0;
  195. int lastIndex, old, end;
  196. if (in.indexOf('-') > -1) {
  197. in = in.replace('-', ':');
  198. }
  199. lastIndex = in.lastIndexOf(':');
  200. if (lastIndex > in.length() - 2) return null;
  201. end = Math.min(in.length(), lastIndex + 3);
  202. ++octets;
  203. old = lastIndex;
  204. while (octets != 5 && lastIndex != -1 && lastIndex > 1) {
  205. lastIndex = in.lastIndexOf(':', --lastIndex);
  206. if (old - lastIndex == 3 || old - lastIndex == 2) {
  207. ++octets;
  208. old = lastIndex;
  209. }
  210. }
  211. if (octets == 5 && lastIndex > 1) {
  212. return in.substring(lastIndex - 2, end).trim();
  213. }
  214. return null;
  215. }
  216. public static void main(String[] args) {
  217. MacAddress addr = MacAddress.getMacAddress();
  218. System.out.println("addr in integer is " + addr.toLong());
  219. System.out.println("addr in bytes is " + NumbersUtil.bytesToString(addr.toByteArray(), 0, addr.toByteArray().length));
  220. System.out.println("addr in char is " + addr.toString(":"));
  221. }
  222. private static final char[] DIGITS = { '0', '1', '2', '3', '4', '5', '6',
  223. '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
  224. /**
  225. * Parses a <code>long</code> from a hex encoded number. This method will skip
  226. * all characters that are not 0-9 and a-f (the String is lower cased first).
  227. * Returns 0 if the String does not contain any interesting characters.
  228. *
  229. * @param s the String to extract a <code>long</code> from, may not be <code>null</code>
  230. * @return a <code>long</code>
  231. * @throws NullPointerException if the String is <code>null</code>
  232. */
  233. public static long parseLong(String s) throws NullPointerException {
  234. s = s.toLowerCase();
  235. long out = 0;
  236. byte shifts = 0;
  237. char c;
  238. for (int i = 0; i < s.length() && shifts < 16; i++) {
  239. c = s.charAt(i);
  240. if ((c > 47) && (c < 58)) {
  241. out <<= 4;
  242. ++shifts;
  243. out |= c - 48;
  244. }
  245. else if ((c > 96) && (c < 103)) {
  246. ++shifts;
  247. out <<= 4;
  248. out |= c - 87;
  249. }
  250. }
  251. return out;
  252. }
  253. /**
  254. * Parses an <code>int</code> from a hex encoded number. This method will skip
  255. * all characters that are not 0-9 and a-f (the String is lower cased first).
  256. * Returns 0 if the String does not contain any interesting characters.
  257. *
  258. * @param s the String to extract an <code>int</code> from, may not be <code>null</code>
  259. * @return an <code>int</code>
  260. * @throws NullPointerException if the String is <code>null</code>
  261. */
  262. public static int parseInt(String s) throws NullPointerException {
  263. s = s.toLowerCase();
  264. int out = 0;
  265. byte shifts = 0;
  266. char c;
  267. for (int i = 0; i < s.length() && shifts < 8; i++) {
  268. c = s.charAt(i);
  269. if ((c > 47) && (c < 58)) {
  270. out <<= 4;
  271. ++shifts;
  272. out |= c - 48;
  273. }
  274. else if ((c > 96) && (c < 103)) {
  275. ++shifts;
  276. out <<= 4;
  277. out |= c - 87;
  278. }
  279. }
  280. return out;
  281. }
  282. /**
  283. * Parses a <code>short</code> from a hex encoded number. This method will skip
  284. * all characters that are not 0-9 and a-f (the String is lower cased first).
  285. * Returns 0 if the String does not contain any interesting characters.
  286. *
  287. * @param s the String to extract a <code>short</code> from, may not be <code>null</code>
  288. * @return a <code>short</code>
  289. * @throws NullPointerException if the String is <code>null</code>
  290. */
  291. public static short parseShort(String s) throws NullPointerException {
  292. s = s.toLowerCase();
  293. short out = 0;
  294. byte shifts = 0;
  295. char c;
  296. for (int i = 0; i < s.length() && shifts < 4; i++) {
  297. c = s.charAt(i);
  298. if ((c > 47) && (c < 58)) {
  299. out <<= 4;
  300. ++shifts;
  301. out |= c - 48;
  302. }
  303. else if ((c > 96) && (c < 103)) {
  304. ++shifts;
  305. out <<= 4;
  306. out |= c - 87;
  307. }
  308. }
  309. return out;
  310. }
  311. /**
  312. * Parses a <code>byte</code> from a hex encoded number. This method will skip
  313. * all characters that are not 0-9 and a-f (the String is lower cased first).
  314. * Returns 0 if the String does not contain any interesting characters.
  315. *
  316. * @param s the String to extract a <code>byte</code> from, may not be <code>null</code>
  317. * @return a <code>byte</code>
  318. * @throws NullPointerException if the String is <code>null</code>
  319. */
  320. public static byte parseByte(String s) throws NullPointerException {
  321. s = s.toLowerCase();
  322. byte out = 0;
  323. byte shifts = 0;
  324. char c;
  325. for (int i = 0; i < s.length() && shifts < 2; i++) {
  326. c = s.charAt(i);
  327. if ((c > 47) && (c < 58)) {
  328. out <<= 4;
  329. ++shifts;
  330. out |= c - 48;
  331. }
  332. else if ((c > 96) && (c < 103)) {
  333. ++shifts;
  334. out <<= 4;
  335. out |= c - 87;
  336. }
  337. }
  338. return out;
  339. }
  340. }