【转】java:多网卡环境下获取MAC地址

http://blog.csdn.net/10km/article/details/78569962

 

JDK6以后 java.net.NetworkInterface提供了完整的方法用于获取网络设备信息。 
调用 NetworkInterface.getNetworkInterfaces()可以返回所有网络设备 
调用NetworkInterface.getHardwareAddress()就可以获取指定网卡的MAC. 
下面的完整代码基于NetworkInterface提供了getNICs方法用于获取指定类型设备,通过指定不同的过滤器(Filter.UP,Filter.ALL…)的组合实现过滤条件订制。 
提供getMacAddress方法用于获取指定设备的MAC地址

NetworkUtil.java

  1 package net.gdface.facelog.device;
  2 
  3 import java.net.InetAddress;
  4 import java.net.NetworkInterface;
  5 import java.net.SocketException;
  6 import java.util.Iterator;
  7 import java.util.List;
  8 import java.util.Set;
  9 
 10 import com.google.common.collect.ImmutableSet;
 11 import com.google.common.collect.Iterators;
 12 
 13 import com.google.common.base.Predicates;
 14 
 15 import com.google.common.base.Joiner;
 16 import com.google.common.base.Predicate;
 17 import com.google.common.collect.Lists;
 18 import com.google.common.primitives.Bytes;
 19 
 20 import com.google.common.base.Function;
 21 
 22 /**
 23  * @author guyadong
 24  *
 25  */
 26 public class NetworkUtil {
 27     public static enum Radix{
 28         /** 二进制 */BIN(2),
 29         /** 十进制 */DEC(10),
 30         /** 十六进制 */HEX(16);
 31         final int value;
 32         Radix(int radix){
 33             this.value = radix;
 34         }
 35     }
 36     public static enum Filter implements Predicate<NetworkInterface>{
 37         /** 过滤器: 所有网卡 */ALL,
 38         /** 过滤器: 在线设备,see also {@link NetworkInterface#isUp()} */UP,
 39         /** 过滤器: 虚拟接口,see also {@link NetworkInterface#isVirtual()} */VIRTUAL,
 40         /** 过滤器:LOOPBACK, see also {@link NetworkInterface#isLoopback()} */LOOPBACK,
 41         /** 过滤器:物理网卡 */PHYICAL_ONLY;
 42 
 43         @Override
 44         public boolean apply(NetworkInterface input) {
 45             if(null == input ){
 46                 return false;
 47             }
 48             try{
 49                 byte[] hardwareAddress;
 50                 switch(this){
 51                 case UP:
 52                     return input.isUp();
 53                 case VIRTUAL:
 54                     return input.isVirtual();
 55                 case LOOPBACK:
 56                     return input.isLoopback();
 57                 case PHYICAL_ONLY :
 58                     hardwareAddress = input.getHardwareAddress();
 59                     return null != hardwareAddress 
 60                             && hardwareAddress.length > 0 
 61                             && !input.isVirtual() 
 62                             && !isVMMac(hardwareAddress);
 63                 case ALL:
 64                 default :
 65                     return true;
 66                 }
 67             } catch (SocketException e) {
 68                 throw new RuntimeException(e);
 69             }
 70         }
 71     }
 72     /**
 73      * 根据过滤器{@code filters}指定的条件(AND)返回网卡设备对象
 74      * @param filters
 75      * @return
 76      */
 77     @SafeVarargs
 78     @SuppressWarnings("unchecked")
 79     public static Set<NetworkInterface> getNICs(Predicate<NetworkInterface> ...filters) {
 80         if(null == filters){
 81             filters = new Predicate[]{Filter.ALL};
 82         }
 83         try {
 84             Iterator<NetworkInterface> filtered = Iterators.filter(
 85                     Iterators.forEnumeration(NetworkInterface.getNetworkInterfaces()),
 86                     Predicates.and(filters));
 87             return ImmutableSet.copyOf(filtered);
 88         } catch (SocketException e) {
 89             throw new RuntimeException(e);
 90         } 
 91     }
 92     /**
 93      * 返回所有物理网卡
 94      * @return
 95      */
 96     public static Set<NetworkInterface> getPhysicalNICs() {
 97         return getNICs(Filter.PHYICAL_ONLY,Filter.UP);
 98     }
 99     /**
100      * 将{@code byte[]} 转换为{@code radix}指定格式的字符串
101      * 
102      * @param source 
103      * @param separator 分隔符
104      * @param radix 进制基数
105      * @return {@code source}为{@code null}时返回空字符串
106      */
107     public static final String format(byte[] source,String separator, final Radix radix) {
108         if (null == source){
109             return "";
110         }
111         if(null == separator){
112             separator = "";
113         }
114         List<String> hex = Lists.transform(Bytes.asList(source),new Function<Byte,String>(){
115             @Override
116             public String apply(Byte input) {
117                 return String.copyValueOf(new char[]{
118                         Character.forDigit((input & 240) >> 4, radix.value),
119                         Character.forDigit(input & 15, radix.value)
120                 });
121             }});
122         return Joiner.on(separator).join(hex);
123     }
124     /** 
125      * MAC地址格式(16进制)格式化{@code source}指定的字节数组 
126      * @see #format(byte[], String, int)
127      */
128     public static final String formatMac(byte[] source,String separator) {
129         return format(source,separator,Radix.HEX);
130     }
131     /** 
132      * 以IP地址格式(点分位)格式化{@code source}指定的字节数组<br>
133      * @see #format(byte[], String, int) 
134      */
135     public static final String formatIp(byte[] source) {
136         return format(source,".",Radix.DEC);
137     }
138     /**
139      * 返回指定{@code address}绑定的网卡的物理地址(MAC)
140      * @param address
141      * @return 指定的{@code address}没有绑定在任何网卡上返回{@code null}
142      * @see {@link NetworkInterface#getByInetAddress(InetAddress)}
143      * @see {@link NetworkInterface#getHardwareAddress()}
144      */
145     public static byte[] getMacAddress(InetAddress address) {
146         try {
147             NetworkInterface nic = NetworkInterface.getByInetAddress(address);
148             return null == nic ? null  : nic.getHardwareAddress();
149         } catch (SocketException e) {
150             throw new RuntimeException(e);
151         }
152     }
153     /**
154      * @param nic 网卡对象
155      * @param separator 格式化分隔符
156      * @return 表示MAC地址的字符串
157      */
158     public static String getMacAddress(NetworkInterface nic,String separator) {
159         try {
160             return format(nic.getHardwareAddress(),separator, Radix.HEX);
161         } catch (SocketException e) {
162             throw new RuntimeException(e);
163         }
164     }
165     /**
166      * 参见 {@link #getMacAddress(InetAddress)}
167      * @param address
168      * @param separator 格式化分隔符
169      * @return 表示MAC地址的字符串
170      */
171     public static String getMacAddress(InetAddress address,String separator) {
172         return format(getMacAddress(address),separator, Radix.HEX);     
173     }
174     private static byte invalidMacs[][] = {
175             {0x00, 0x05, 0x69},             // VMWare
176             {0x00, 0x1C, 0x14},             // VMWare
177             {0x00, 0x0C, 0x29},             // VMWare
178             {0x00, 0x50, 0x56},             // VMWare
179             {0x08, 0x00, 0x27},             // Virtualbox
180             {0x0A, 0x00, 0x27},             // Virtualbox
181             {0x00, 0x03, (byte)0xFF},       // Virtual-PC
182             {0x00, 0x15, 0x5D}              // Hyper-V
183     };
184     private static boolean isVMMac(byte[] mac) {
185         if(null == mac) {
186             return false;
187         }
188 
189         for (byte[] invalid: invalidMacs){
190             if (invalid[0] == mac[0] && invalid[1] == mac[1] && invalid[2] == mac[2]) {
191                 return true;
192             }
193         }
194 
195         return false;
196     }
197 
198 }

 

posted @ 2018-02-05 19:15  kira2will  阅读(989)  评论(0编辑  收藏  举报