|
19 | 19 |
|
20 | 20 | package com.cloud.utils.net; |
21 | 21 |
|
22 | | -import static com.cloud.utils.AutoCloseableUtil.closeAutoCloseable; |
23 | | - |
24 | | -import java.io.BufferedReader; |
25 | | -import java.io.File; |
26 | | -import java.io.IOException; |
27 | | -import java.io.InputStreamReader; |
28 | 22 | import java.net.InetAddress; |
| 23 | +import java.net.NetworkInterface; |
| 24 | +import java.net.SocketException; |
29 | 25 | import java.net.UnknownHostException; |
| 26 | +import java.util.Enumeration; |
30 | 27 | import java.util.Formatter; |
31 | 28 |
|
32 | | -import org.apache.log4j.Logger; |
33 | | - |
34 | 29 | /** |
35 | 30 | * This class retrieves the (first) MAC address for the machine is it is loaded on and stores it statically for retrieval. |
36 | 31 | * It can also be used for formatting MAC addresses. |
37 | | - * copied fnd addpeted rom the public domain utility from John Burkard. |
38 | 32 | **/ |
39 | 33 | public class MacAddress { |
40 | | - private static final Logger s_logger = Logger.getLogger(MacAddress.class); |
41 | 34 | private long _addr = 0; |
42 | 35 |
|
43 | 36 | protected MacAddress() { |
@@ -79,209 +72,45 @@ public String toString() { |
79 | 72 | static { |
80 | 73 | String macAddress = null; |
81 | 74 |
|
82 | | - Process p = null; |
83 | | - BufferedReader in = null; |
84 | | - |
85 | 75 | try { |
86 | | - String osname = System.getProperty("os.name"); |
87 | | - |
88 | | - if (osname.startsWith("Windows")) { |
89 | | - p = Runtime.getRuntime().exec(new String[] {"ipconfig", "/all"}, null); |
90 | | - } else if (osname.startsWith("Solaris") || osname.startsWith("SunOS")) { |
91 | | - // Solaris code must appear before the generic code |
92 | | - String hostName = MacAddress.getFirstLineOfCommand(new String[] {"uname", "-n"}); |
93 | | - if (hostName != null) { |
94 | | - p = Runtime.getRuntime().exec(new String[] {"/usr/sbin/arp", hostName}, null); |
95 | | - } |
96 | | - } else if (new File("/usr/sbin/lanscan").exists()) { |
97 | | - p = Runtime.getRuntime().exec(new String[] {"/usr/sbin/lanscan"}, null); |
98 | | - } else if (new File("/sbin/ifconfig").exists()) { |
99 | | - p = Runtime.getRuntime().exec(new String[] {"/sbin/ifconfig", "-a"}, null); |
100 | | - } |
101 | | - |
102 | | - if (p != null) { |
103 | | - in = new BufferedReader(new InputStreamReader(p.getInputStream()), 128); |
104 | | - String l = null; |
105 | | - while ((l = in.readLine()) != null) { |
106 | | - macAddress = MacAddress.parse(l); |
107 | | - if (macAddress != null) { |
108 | | - short parsedShortMacAddress = MacAddress.parseShort(macAddress); |
109 | | - if (parsedShortMacAddress != 0xff && parsedShortMacAddress != 0x00) |
110 | | - break; |
111 | | - } |
112 | | - macAddress = null; |
113 | | - } |
114 | | - } |
115 | | - |
116 | | - } catch (SecurityException ex) { |
117 | | - s_logger.info("[ignored] security exception in static initializer of MacAddress", ex); |
118 | | - } catch (IOException ex) { |
119 | | - s_logger.info("[ignored] io exception in static initializer of MacAddress"); |
120 | | - } finally { |
121 | | - if (p != null) { |
122 | | - closeAutoCloseable(in, "closing init process input stream"); |
123 | | - closeAutoCloseable(p.getErrorStream(), "closing init process error output stream"); |
124 | | - closeAutoCloseable(p.getOutputStream(), "closing init process std output stream"); |
125 | | - p.destroy(); |
126 | | - } |
| 76 | + Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces(); |
| 77 | + while (networkInterfaces.hasMoreElements()) { |
| 78 | + NetworkInterface network = networkInterfaces.nextElement(); |
| 79 | + final byte [] mac = network.getHardwareAddress(); |
| 80 | + if (mac != null && !network.isVirtual() && |
| 81 | + !network.getName().startsWith("br-") && |
| 82 | + !network.getName().startsWith("veth") && |
| 83 | + !network.getName().startsWith("vnet")) { |
| 84 | + StringBuilder macAddressBuilder = new StringBuilder(); |
| 85 | + for (byte b : mac) { |
| 86 | + macAddressBuilder.append(String.format("%02X", b)); |
| 87 | + } |
| 88 | + macAddress = macAddressBuilder.toString(); |
| 89 | + } |
| 90 | + } |
| 91 | + } catch (SocketException ignore) { |
127 | 92 | } |
128 | 93 |
|
129 | | - long clockSeqAndNode = 0; |
| 94 | + long macAddressInLong = 0; |
130 | 95 |
|
131 | 96 | if (macAddress != null) { |
132 | | - if (macAddress.indexOf(':') != -1) { |
133 | | - clockSeqAndNode |= MacAddress.parseLong(macAddress); |
134 | | - } else if (macAddress.startsWith("0x")) { |
135 | | - clockSeqAndNode |= MacAddress.parseLong(macAddress.substring(2)); |
136 | | - } |
| 97 | + macAddressInLong = Long.parseLong(macAddress, 16); |
137 | 98 | } else { |
138 | 99 | try { |
139 | 100 | byte[] local = InetAddress.getLocalHost().getAddress(); |
140 | | - clockSeqAndNode |= (local[0] << 24) & 0xFF000000L; |
141 | | - clockSeqAndNode |= (local[1] << 16) & 0xFF0000; |
142 | | - clockSeqAndNode |= (local[2] << 8) & 0xFF00; |
143 | | - clockSeqAndNode |= local[3] & 0xFF; |
| 101 | + macAddressInLong |= (local[0] << 24) & 0xFF000000L; |
| 102 | + macAddressInLong |= (local[1] << 16) & 0xFF0000; |
| 103 | + macAddressInLong |= (local[2] << 8) & 0xFF00; |
| 104 | + macAddressInLong |= local[3] & 0xFF; |
144 | 105 | } catch (UnknownHostException ex) { |
145 | | - clockSeqAndNode |= (long)(Math.random() * 0x7FFFFFFF); |
| 106 | + macAddressInLong |= (long)(Math.random() * 0x7FFFFFFF); |
146 | 107 | } |
147 | 108 | } |
148 | 109 |
|
149 | | - s_address = new MacAddress(clockSeqAndNode); |
| 110 | + s_address = new MacAddress(macAddressInLong); |
150 | 111 | } |
151 | 112 |
|
152 | 113 | public static MacAddress getMacAddress() { |
153 | 114 | return s_address; |
154 | 115 | } |
155 | | - |
156 | | - private static String getFirstLineOfCommand(String[] commands) throws IOException { |
157 | | - |
158 | | - Process p = null; |
159 | | - BufferedReader reader = null; |
160 | | - |
161 | | - try { |
162 | | - p = Runtime.getRuntime().exec(commands); |
163 | | - reader = new BufferedReader(new InputStreamReader(p.getInputStream()), 128); |
164 | | - |
165 | | - return reader.readLine(); |
166 | | - } finally { |
167 | | - if (p != null) { |
168 | | - closeAutoCloseable(reader, "closing process input stream"); |
169 | | - closeAutoCloseable(p.getErrorStream(), "closing process error output stream"); |
170 | | - closeAutoCloseable(p.getOutputStream(), "closing process std output stream"); |
171 | | - p.destroy(); |
172 | | - } |
173 | | - } |
174 | | - |
175 | | - } |
176 | | - |
177 | | - /** |
178 | | - * The MAC address parser attempts to find the following patterns: |
179 | | - * <ul> |
180 | | - * <li>.{1,2}:.{1,2}:.{1,2}:.{1,2}:.{1,2}:.{1,2}</li> |
181 | | - * <li>.{1,2}-.{1,2}-.{1,2}-.{1,2}-.{1,2}-.{1,2}</li> |
182 | | - * </ul> |
183 | | - * |
184 | | - * This is copied from the author below. The author encouraged copying |
185 | | - * it. |
186 | | - * |
187 | | - */ |
188 | | - static String parse(String in) { |
189 | | - |
190 | | - // lanscan |
191 | | - |
192 | | - int hexStart = in.indexOf("0x"); |
193 | | - if (hexStart != -1) { |
194 | | - int hexEnd = in.indexOf(' ', hexStart); |
195 | | - if (hexEnd != -1) { |
196 | | - return in.substring(hexStart, hexEnd); |
197 | | - } |
198 | | - } |
199 | | - |
200 | | - int octets = 0; |
201 | | - int lastIndex, old, end; |
202 | | - |
203 | | - if (in.indexOf('-') > -1) { |
204 | | - in = in.replace('-', ':'); |
205 | | - } |
206 | | - |
207 | | - lastIndex = in.lastIndexOf(':'); |
208 | | - |
209 | | - if (lastIndex > in.length() - 2) |
210 | | - return null; |
211 | | - |
212 | | - end = Math.min(in.length(), lastIndex + 3); |
213 | | - |
214 | | - ++octets; |
215 | | - old = lastIndex; |
216 | | - while (octets != 5 && lastIndex != -1 && lastIndex > 1) { |
217 | | - lastIndex = in.lastIndexOf(':', --lastIndex); |
218 | | - if (old - lastIndex == 3 || old - lastIndex == 2) { |
219 | | - ++octets; |
220 | | - old = lastIndex; |
221 | | - } |
222 | | - } |
223 | | - |
224 | | - if (octets == 5 && lastIndex > 1) { |
225 | | - return in.substring(lastIndex - 2, end).trim(); |
226 | | - } |
227 | | - return null; |
228 | | - } |
229 | | - |
230 | | - /** |
231 | | - * Parses a <code>long</code> from a hex encoded number. This method will skip |
232 | | - * all characters that are not 0-9 and a-f (the String is lower cased first). |
233 | | - * Returns 0 if the String does not contain any interesting characters. |
234 | | - * |
235 | | - * @param s the String to extract a <code>long</code> from, may not be <code>null</code> |
236 | | - * @return a <code>long</code> |
237 | | - * @throws NullPointerException if the String is <code>null</code> |
238 | | - */ |
239 | | - private static long parseLong(String s) throws NullPointerException { |
240 | | - s = s.toLowerCase(); |
241 | | - long out = 0; |
242 | | - byte shifts = 0; |
243 | | - char c; |
244 | | - for (int i = 0; i < s.length() && shifts < 16; i++) { |
245 | | - c = s.charAt(i); |
246 | | - if ((c > 47) && (c < 58)) { |
247 | | - out <<= 4; |
248 | | - ++shifts; |
249 | | - out |= c - 48; |
250 | | - } else if ((c > 96) && (c < 103)) { |
251 | | - ++shifts; |
252 | | - out <<= 4; |
253 | | - out |= c - 87; |
254 | | - } |
255 | | - } |
256 | | - return out; |
257 | | - } |
258 | | - |
259 | | - /** |
260 | | - * Parses a <code>short</code> from a hex encoded number. This method will skip |
261 | | - * all characters that are not 0-9 and a-f (the String is lower cased first). |
262 | | - * Returns 0 if the String does not contain any interesting characters. |
263 | | - * |
264 | | - * @param s the String to extract a <code>short</code> from, may not be <code>null</code> |
265 | | - * @return a <code>short</code> |
266 | | - * @throws NullPointerException if the String is <code>null</code> |
267 | | - */ |
268 | | - private static short parseShort(String s) throws NullPointerException { |
269 | | - s = s.toLowerCase(); |
270 | | - short out = 0; |
271 | | - byte shifts = 0; |
272 | | - char c; |
273 | | - for (int i = 0; i < s.length() && shifts < 4; i++) { |
274 | | - c = s.charAt(i); |
275 | | - if ((c > 47) && (c < 58)) { |
276 | | - out <<= 4; |
277 | | - ++shifts; |
278 | | - out |= c - 48; |
279 | | - } else if ((c > 96) && (c < 103)) { |
280 | | - ++shifts; |
281 | | - out <<= 4; |
282 | | - out |= c - 87; |
283 | | - } |
284 | | - } |
285 | | - return out; |
286 | | - } |
287 | 116 | } |
0 commit comments