ce3139230324aefd0be1a1a97bd8c71b45e907e4
[lispflowmapping.git] / mappingservice / implementation / src / main / java / org / opendaylight / lispflowmapping / implementation / util / MaskUtil.java
1 /*
2  * Copyright (c) 2014 Contextream, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.lispflowmapping.implementation.util;
9
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;
15
16 import org.apache.commons.lang3.exception.ExceptionUtils;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.LispAFIAddress;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lcafsegmentaddress.AddressBuilder;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lcafsegmentaddress.Address;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.ipv4.Ipv4Address;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.ipv6.Ipv6Address;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.lcafsegment.LcafSegmentAddr;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.lcafsegment.LcafSegmentAddrBuilder;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 public class MaskUtil {
28     private static final Logger LOG = LoggerFactory.getLogger(MaskUtil.class);
29     public static boolean isMaskable(LispAFIAddress address) {
30         if (address instanceof Ipv4Address || address instanceof Ipv6Address
31                 || address instanceof LcafSegmentAddr) {
32             return true;
33         }
34         return false;
35     }
36
37     public static LispAFIAddress normalize(LispAFIAddress address, int mask) {
38         try {
39             if (address instanceof Ipv4Address) {
40                 return LispAFIConvertor.asIPAfiAddress(normalizeIP(Inet4Address.getByName(((Ipv4Address) address)
41                         .getIpv4Address().getValue()), mask).getHostAddress());
42             } else if (address instanceof Ipv6Address) {
43                 return  LispAFIConvertor.asIPv6AfiAddress(normalizeIP(Inet6Address.getByName(((Ipv6Address) address)
44                         .getIpv6Address().getValue()), mask).getHostAddress());
45             } else if (address instanceof LcafSegmentAddr) {
46                 LcafSegmentAddr segAddr = (LcafSegmentAddr) address;
47                 Address normalizedAddr = new AddressBuilder().setPrimitiveAddress(LispAFIConvertor.toPrimitive(
48                         normalizeIpAddress(LispAFIConvertor.toAFIfromPrimitive(segAddr.getAddress()
49                         .getPrimitiveAddress()), mask))).build();
50                 return new LcafSegmentAddrBuilder(segAddr).setAddress(normalizedAddr).build();
51             }
52         } catch (UnknownHostException e) {
53             LOG.trace("Failed to normalize " + address + ": " + ExceptionUtils.getStackTrace(e));
54             return null;
55         }
56         return null;
57     }
58
59     private static LispAFIAddress normalizeIpAddress(LispAFIAddress address, int mask) throws UnknownHostException {
60         if (address instanceof Ipv4Address) {
61             return LispAFIConvertor.asIPAfiAddress(normalizeIP(Inet4Address.getByName(((Ipv4Address) address)
62                     .getIpv4Address().getValue()), mask).getHostAddress());
63         } else if (address instanceof Ipv6Address) {
64             return  LispAFIConvertor.asIPv6AfiAddress(normalizeIP(Inet6Address.getByName(((Ipv6Address) address)
65                     .getIpv6Address().getValue()), mask).getHostAddress());
66         }
67         throw new UnknownHostException("Address + " + address + " not an IPv4 or IPv6 address");
68     }
69
70     private static InetAddress normalizeIP(InetAddress address, int mask) throws UnknownHostException {
71         ByteBuffer byteRepresentation = ByteBuffer.wrap(address.getAddress());
72         byte b = (byte) 0xff;
73         for (int i = 0; i < byteRepresentation.array().length; i++) {
74             if (mask >= 8)
75                 byteRepresentation.put(i, (byte) (b & byteRepresentation.get(i)));
76
77             else if (mask > 0) {
78                 byteRepresentation.put(i, (byte) ((byte) (b << (8 - mask)) & byteRepresentation.get(i)));
79             } else {
80                 byteRepresentation.put(i, (byte) (0 & byteRepresentation.get(i)));
81             }
82
83             mask -= 8;
84         }
85         return InetAddress.getByAddress(byteRepresentation.array());
86     }
87
88     public static int getMaxMask(LispAFIAddress address) {
89         if (address instanceof Ipv4Address) {
90             return 32;
91         }
92         if (address instanceof Ipv6Address) {
93             return 128;
94         }
95         return -1;
96     }
97
98     public static byte getMaxMaskForAfi(int afi) {
99         if (afi == 1) {
100             return (byte) 32;
101         } else if (afi == 2){
102             return (byte) 128;
103         } else {
104             return (byte) -1;
105         }
106     }
107 }