2 * Copyright (c) 2014 Contextream, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.lispflowmapping.lisp.util;
10 import java.net.Inet4Address;
11 import java.net.Inet6Address;
12 import java.net.InetAddress;
13 import java.net.UnknownHostException;
14 import java.nio.ByteBuffer;
16 import org.apache.commons.lang3.exception.ExceptionUtils;
17 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.SimpleAddress;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.Address;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.InstanceId;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv4;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv4Prefix;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv6;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv6Prefix;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.ServicePath;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.SourceDestKey;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
31 public final class MaskUtil {
32 private static final Logger LOG = LoggerFactory.getLogger(MaskUtil.class);
33 private static final short IPV4_MAX_MASK = 32;
34 private static final short IPV6_MAX_MASK = 128;
36 // Utility class, should not be instantiated
40 public static boolean isMaskable(Address address) {
41 if (address instanceof Ipv4Prefix || address instanceof Ipv6Prefix || address instanceof SourceDestKey) {
43 } else if (address instanceof InstanceId) {
44 return isMaskable(((InstanceId)address).getInstanceId().getAddress());
49 public static boolean isMaskable(SimpleAddress address) {
50 if (address.getIpPrefix() != null) {
56 public static Eid normalize(Eid eid, short mask) {
57 Address address = eid.getAddress();
59 if (address instanceof Ipv4Prefix) {
60 String[] v4prefix = String.valueOf(((Ipv4Prefix)address).getIpv4Prefix().getValue()).split("/");
61 InetAddress normalized = normalizeIP(Inet4Address.getByName(v4prefix[0]), mask);
62 return LispAddressUtil.asIpv4PrefixEid(eid, (Inet4Address)normalized, mask);
63 } else if (address instanceof Ipv6Prefix) {
64 String[] v6prefix = String.valueOf(((Ipv6Prefix)address).getIpv6Prefix().getValue()).split("/");
65 InetAddress normalized = normalizeIP(Inet6Address.getByName(v6prefix[0]), mask);
66 return LispAddressUtil.asIpv6PrefixEid(eid, (Inet6Address)normalized, mask);
67 } else if (address instanceof InstanceId) {
68 // TODO - not absolutely necessary, but should be implemented
71 } catch (UnknownHostException e) {
72 LOG.trace("Failed to normalize eid {} with mask {}: {}", eid, mask, ExceptionUtils.getStackTrace(e));
77 public static Eid normalize(Eid eid) {
78 Address address = eid.getAddress();
80 if (address instanceof Ipv4Prefix) {
81 String[] v4prefix = String.valueOf(((Ipv4Prefix)address).getIpv4Prefix().getValue()).split("/");
82 short mask = Short.parseShort(v4prefix[1]);
83 InetAddress normalized = normalizeIP(Inet4Address.getByName(v4prefix[0]), mask);
84 return LispAddressUtil.asIpv4PrefixEid(eid, (Inet4Address)normalized, mask);
85 } else if (address instanceof Ipv6Prefix) {
86 String[] v6prefix = String.valueOf(((Ipv6Prefix)address).getIpv6Prefix().getValue()).split("/");
87 short mask = Short.parseShort(v6prefix[1]);
88 InetAddress normalized = normalizeIP(Inet6Address.getByName(v6prefix[0]), mask);
89 return LispAddressUtil.asIpv6PrefixEid(eid, (Inet6Address)normalized, mask);
90 } else if (address instanceof InstanceId) {
91 // TODO - not absolutely necessary, but should be implemented
93 } else if (address instanceof ServicePath) {
94 // Build new Service Path eid with service index set to 0
95 long spi = ((ServicePath) address).getServicePath().getServicePathId().getValue();
96 long vni = eid.getVirtualNetworkId() != null ? eid.getVirtualNetworkId().getValue() : -1;
97 return LispAddressUtil.asServicePathEid(vni, spi, (short)0);
99 } catch (UnknownHostException e) {
100 LOG.trace("Failed to normalize eid {}: {}", eid, ExceptionUtils.getStackTrace(e));
105 private static InetAddress normalizeIP(InetAddress address, int maskLength) throws UnknownHostException {
106 ByteBuffer byteRepresentation = ByteBuffer.wrap(address.getAddress());
107 byte b = (byte) 0xff;
108 int mask = maskLength;
109 for (int i = 0; i < byteRepresentation.array().length; i++) {
111 byteRepresentation.put(i, (byte) (b & byteRepresentation.get(i)));
112 } else if (mask > 0) {
113 byteRepresentation.put(i, (byte) ((byte) (b << (8 - mask)) & byteRepresentation.get(i)));
115 byteRepresentation.put(i, (byte) (0 & byteRepresentation.get(i)));
120 return InetAddress.getByAddress(byteRepresentation.array());
123 public static int getMaxMask(Address address) {
124 if (address instanceof Ipv4 || address instanceof Ipv4Prefix) {
125 return IPV4_MAX_MASK;
126 } else if (address instanceof Ipv6 || address instanceof Ipv6Prefix) {
127 return IPV6_MAX_MASK;
133 public static short getMaskForAddress(SimpleAddress address) {
134 if (address.getIpPrefix() == null) {
137 return getMaskForIpPrefix(address.getIpPrefix());
140 public static short getMaskForIpPrefix(IpPrefix prefix) {
141 return Short.parseShort(String.valueOf(prefix.getValue()).split("/")[1]);
144 public static String getAddressStringForIpPrefix(IpPrefix prefix) {
145 return String.valueOf(prefix.getValue()).split("/")[0];
148 public static String getAddressStringForIpv4Prefix(Ipv4Prefix prefix) {
149 return String.valueOf(prefix.getIpv4Prefix().getValue()).split("/")[0];
152 public static String getAddressStringForIpv6Prefix(Ipv6Prefix prefix) {
153 return String.valueOf(prefix.getIpv6Prefix().getValue()).split("/")[0];
156 public static short getMaskForAddress(Address address) {
157 if (address instanceof Ipv4) {
158 return IPV4_MAX_MASK;
159 } else if (address instanceof Ipv6) {
160 return IPV6_MAX_MASK;
161 } else if (address instanceof Ipv4Prefix) {
162 String[] prefix = String.valueOf(((Ipv4Prefix)address).getIpv4Prefix().getValue()).split("/"); // TODO use something more efficient
163 return Short.parseShort(prefix[1]);
164 } else if (address instanceof Ipv6Prefix) {
165 String[] prefix = String.valueOf(((Ipv6Prefix)address).getIpv6Prefix().getValue()).split("/"); // TODO use something more efficient
166 return Short.parseShort(prefix[1]);
167 } else if (address instanceof InstanceId) {
168 return getMaskForAddress(((InstanceId)address).getInstanceId().getAddress());