/*_##########################################################################
_##
_## Copyright (C) 2011 Kaito Yamada
_##
_##########################################################################
*/
package com.github.kaitoy.sneo.network;
import java.net.InetAddress;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.pcap4j.packet.namednumber.Oui;
import org.pcap4j.util.ByteArrays;
import org.pcap4j.util.MacAddress;
public class MacAddressManager {
public static final Oui VIRTUAL_MACADDRESS_OUI
= Oui.getInstance(new byte[] { (byte)0xFE, (byte)0, (byte)0 });
private static final MacAddressManager INSTANCE
= new MacAddressManager();
private static final int MAX_SERIAL_NUMBER
= ByteArrays.getInt(
new byte[] { (byte)0, (byte)0xFF, (byte)0xFF, (byte)0xFF },
0
);
private final Map<InetAddress, MacAddress> registry
= new ConcurrentHashMap<InetAddress, MacAddress>();
private final Object counterLock = new Object();
private int counter = 0;
private MacAddressManager() {}
public static MacAddressManager getInstance() { return INSTANCE; }
public MacAddress generateVirtualMacAddress() {
int serialNumber;
synchronized (counterLock) {
if (counter > MAX_SERIAL_NUMBER) {
throw new AssertionError("too many MAC addresses.");
}
serialNumber = counter;
counter++;
}
// TODO IPv6
byte[] rawAddr = new byte[6];
System.arraycopy(
VIRTUAL_MACADDRESS_OUI.valueAsByteArray(), 0, rawAddr, 0, 3
);
System.arraycopy(
ByteArrays.toByteArray(serialNumber), 1, rawAddr, 3, 3
);
MacAddress macAddr = MacAddress.getByAddress(rawAddr);
return macAddr;
}
public boolean isVirtualMacAddress(MacAddress macAddress) {
return macAddress.getOui().equals(VIRTUAL_MACADDRESS_OUI);
}
public MacAddress resolveVirtualAddress(InetAddress ipAddr) {
return registry.get(ipAddr);
}
public void registerVirtualMacAddress(InetAddress ipAddr, MacAddress macAddr) {
registry.put(ipAddr, macAddr);
}
}