Adds utility functions related to the link local addresses
Change-Id: I26045542d4f9d60a0d7d0905087136b995f8c03e
diff --git a/utils/misc/src/main/java/org/onlab/packet/IPv6.java b/utils/misc/src/main/java/org/onlab/packet/IPv6.java
index f466ca4..e88998d 100644
--- a/utils/misc/src/main/java/org/onlab/packet/IPv6.java
+++ b/utils/misc/src/main/java/org/onlab/packet/IPv6.java
@@ -30,6 +30,7 @@
import java.util.Map;
import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkArgument;
import static org.onlab.packet.PacketUtils.checkInput;
/**
@@ -48,6 +49,8 @@
public static final byte PROTOCOL_AH = 0x33;
public static final byte PROTOCOL_DSTOPT = 0x3C;
+ public static final byte LINK_LOCAL_0 = (byte) 0xfe;
+ public static final byte LINK_LOCAL_1 = (byte) 0x80;
public static final Map<Byte, Deserializer<? extends IPacket>> PROTOCOL_DESERIALIZER_MAP =
new HashMap<>();
@@ -396,8 +399,9 @@
* @param targetIp the unicast or anycast address
* @return the computed solicitation node address
*/
- public static byte[] solicitationNodeAddress(byte[] targetIp) {
- return targetIp.length != Ip6Address.BYTE_LENGTH ? null : new byte[] {
+ public static byte[] getSolicitNodeAddress(byte[] targetIp) {
+ checkArgument(targetIp.length == Ip6Address.BYTE_LENGTH);
+ return new byte[] {
(byte) 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, (byte) 0xff,
targetIp[targetIp.length - 3],
@@ -424,8 +428,9 @@
* @param targetIp the multicast address.
* @return the multicast mac address
*/
- public static byte[] multicastMacAddress(byte[] targetIp) {
- return targetIp.length != Ip6Address.BYTE_LENGTH ? null : new byte[] {
+ public static byte[] getMCastMacAddress(byte[] targetIp) {
+ checkArgument(targetIp.length == Ip6Address.BYTE_LENGTH);
+ return new byte[] {
0x33, 0x33,
targetIp[targetIp.length - 4],
targetIp[targetIp.length - 3],
@@ -433,4 +438,70 @@
targetIp[targetIp.length - 1],
};
}
+
+ /**
+ * According to the RFC 4291, an IPv6 link local address is an IPv6
+ * unicast address that can be automatically configured on any interface
+ * using the link-local prefix FE80::/10 (1111 1110 10) and the interface
+ * identifier in the modified EUI-64 format.
+ *
+ * +----------------------------------------------------------------+
+ * | 10 bits | 54 bits | 64 bits |
+ * +----------- +-------------------------+-------------------------+
+ * | 1111111010 | 0 | interface ID |
+ * +----------- +-------------------------+-------------------------+
+ *
+ * @param targetIp the ip address to verify
+ * @return true if the ipv6 address is link local,
+ * false otherwise
+ */
+ public static boolean isLinkLocalAddress(byte[] targetIp) {
+ checkArgument(targetIp.length == Ip6Address.BYTE_LENGTH);
+ return (targetIp[0] & 0xff) == 0xfe && (targetIp[1] & 0xc0) == 0x80;
+ }
+
+ /**
+ * Returns the auto-generated link local address using the
+ * mac address as parameter.
+ *
+ * @param macAddress the mac address to use
+ * @return the ipv6 link local address
+ */
+ public static byte[] getLinkLocalAddress(byte[] macAddress) {
+ checkArgument(macAddress.length == MacAddress.MAC_ADDRESS_LENGTH);
+ return new byte[] {
+ LINK_LOCAL_0,
+ LINK_LOCAL_1,
+ 0, 0, 0, 0, 0, 0,
+ (byte) (macAddress[0] ^ (1 << 1)),
+ macAddress[1],
+ macAddress[2],
+ (byte) 0xff,
+ (byte) 0xfe,
+ macAddress[3],
+ macAddress[4],
+ macAddress[5],
+ };
+ }
+
+ /**
+ * Returns the mac address from the auto-generated
+ * link local address.
+ *
+ * @param linkLocalAddress the ipv6 to use
+ * @return the mac address
+ */
+ public static byte[] getMacAddress(byte[] linkLocalAddress) {
+ return !isLinkLocalAddress(linkLocalAddress) ? null : new byte[] {
+ (byte) (linkLocalAddress[8] ^ (1 << 1)),
+ linkLocalAddress[9],
+ linkLocalAddress[10],
+ linkLocalAddress[13],
+ linkLocalAddress[14],
+ linkLocalAddress[15],
+ };
+ }
+
+
+
}