Update DAO API
[lispflowmapping.git] / mappingservice / lisp-proto / src / main / java / org / opendaylight / lispflowmapping / lisp / 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.lisp.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.lisp.proto.rev150820.LcafSegmentAddress;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.LcafSourceDestAddress;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.LispAFIAddress;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.LispIpv4Address;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.LispIpv6Address;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lcafsegmentaddress.AddressBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lcafsegmentaddress.Address;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lcafsourcedestaddress.DstAddress;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lcafsourcedestaddress.DstAddressBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lcafsourcedestaddress.SrcAddress;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lcafsourcedestaddress.SrcAddressBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lispaddress.LispAddressContainer;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lispaddress.LispAddressContainerBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lispaddress.lispaddresscontainer.address.Ipv4;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lispaddress.lispaddresscontainer.address.Ipv4Builder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lispaddress.lispaddresscontainer.address.Ipv6;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lispaddress.lispaddresscontainer.address.Ipv6Builder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lispaddress.lispaddresscontainer.address.LcafSegmentBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lispaddress.lispaddresscontainer.address.LcafSourceDest;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lispaddress.lispaddresscontainer.address.LcafSourceDestBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lispaddress.lispaddresscontainer.address.ipv4.Ipv4Address;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lispaddress.lispaddresscontainer.address.ipv4.Ipv4AddressBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lispaddress.lispaddresscontainer.address.ipv6.Ipv6Address;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lispaddress.lispaddresscontainer.address.ipv6.Ipv6AddressBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lispaddress.lispaddresscontainer.address.lcafsegment.LcafSegmentAddr;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lispaddress.lispaddresscontainer.address.lcafsegment.LcafSegmentAddrBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lispaddress.lispaddresscontainer.address.lcafsourcedest.LcafSourceDestAddr;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.lispaddress.lispaddresscontainer.address.lcafsourcedest.LcafSourceDestAddrBuilder;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 public class MaskUtil {
49     private static final Logger LOG = LoggerFactory.getLogger(MaskUtil.class);
50     public static boolean isMaskable(LispAFIAddress address) {
51         if (address instanceof Ipv4Address || address instanceof Ipv6Address || address instanceof LcafSegmentAddr) {
52             return true;
53         }
54         return false;
55     }
56
57     public static boolean isMaskable(LispAddressContainer address) {
58         if (address.getAddress() instanceof Ipv4  || address.getAddress() instanceof Ipv6) {
59             return true;
60         } else if (address.getAddress() instanceof LcafSegmentAddress) {
61             return isMaskable(LispAFIConvertor.toAFIfromPrimitive(((LcafSegmentAddress) address).getAddress()
62                     .getPrimitiveAddress()));
63         } else if (address.getAddress() instanceof LcafSourceDestAddress) {
64             LcafSourceDestAddr sd = ((LcafSourceDest) address.getAddress()).getLcafSourceDestAddr();
65             return isMaskable(LispAFIConvertor.toAFIfromPrimitive(sd.getSrcAddress().getPrimitiveAddress()))
66                     && isMaskable(LispAFIConvertor.toAFIfromPrimitive(sd.getDstAddress().getPrimitiveAddress()));
67         }
68         return false;
69     }
70
71     public static LispAFIAddress normalize(LispAFIAddress address, short mask) {
72         try {
73             if (address instanceof Ipv4Address) {
74                 return LispAFIConvertor.asIPAfiAddress(normalizeIP(
75                         Inet4Address.getByName(((Ipv4Address) address).getIpv4Address().getValue()),
76                         mask).getHostAddress());
77             } else if (address instanceof Ipv6Address) {
78                 return LispAFIConvertor.asIPv6AfiAddress(normalizeIP(
79                         Inet6Address.getByName(((Ipv6Address) address).getIpv6Address().getValue()),
80                         mask).getHostAddress());
81             } else if (address instanceof LcafSegmentAddr) {
82                 LcafSegmentAddr segAddr = (LcafSegmentAddr) address;
83                 LispAFIAddress afiAddr = LispAFIConvertor
84                         .toAFIfromPrimitive(segAddr.getAddress().getPrimitiveAddress());
85                 Address normalizedAddr = new AddressBuilder().setPrimitiveAddress(
86                         LispAFIConvertor.toPrimitive(normalize(afiAddr, mask))).build();
87                 return new LcafSegmentAddrBuilder(segAddr).setAddress(normalizedAddr).build();
88             }
89         } catch (UnknownHostException e) {
90             LOG.trace("Failed to normalize " + address + ": " + ExceptionUtils.getStackTrace(e));
91         }
92         return address;
93     }
94
95     public static LispAFIAddress normalize(LispAFIAddress address) {
96         if (address instanceof Ipv4Address) {
97             return normalize(address, ((Ipv4Address) address).getMask());
98         } else if (address instanceof Ipv6Address) {
99             return normalize(address, ((Ipv6Address) address).getMask());
100         } else if (address instanceof LcafSegmentAddr) {
101             LcafSegmentAddr segAddr = (LcafSegmentAddr) address;
102             LispAFIAddress afiAddr = LispAFIConvertor.toAFIfromPrimitive(segAddr.getAddress().getPrimitiveAddress());
103             short mask = getMaskForAfiAddress(afiAddr);
104             if (mask == 0) {
105                 return address;
106             }
107             Address normalizedAddr = new AddressBuilder().setPrimitiveAddress(
108                     LispAFIConvertor.toPrimitive(normalize(afiAddr, mask))).build();
109             return new LcafSegmentAddrBuilder(segAddr).setAddress(normalizedAddr).build();
110         }
111         return address;
112     }
113
114     public static LispAddressContainer normalize(LispAddressContainer address, short mask) {
115         try {
116             if (address.getAddress() instanceof Ipv4) {
117                 return LispAFIConvertor.asIPv4Prefix(normalizeIP(
118                         Inet4Address.getByName(((Ipv4) address.getAddress()).getIpv4Address().getIpv4Address().getValue()),
119                         mask).getHostAddress(), mask);
120             } else if (address.getAddress() instanceof Ipv6) {
121                 return LispAFIConvertor.asIPv6Prefix(normalizeIP(
122                         Inet6Address.getByName(((Ipv6) address.getAddress()).getIpv6Address().getIpv6Address().getValue()),
123                         mask).getHostAddress(), mask);
124             } else if (address instanceof LcafSegmentAddress) {
125                 LcafSegmentAddress segAddr = (LcafSegmentAddress) address;
126                 LispAFIAddress afiAddr = LispAFIConvertor
127                         .toAFIfromPrimitive(segAddr.getAddress().getPrimitiveAddress());
128                 Address normalizedAddr = new AddressBuilder().setPrimitiveAddress(
129                         LispAFIConvertor.toPrimitive(normalize(afiAddr, mask))).build();
130                 return new LispAddressContainerBuilder().setAddress(
131                         new LcafSegmentBuilder().setLcafSegmentAddr(
132                                 new LcafSegmentAddrBuilder(segAddr).setAddress(normalizedAddr).build()).build())
133                         .build();
134             }
135         } catch (UnknownHostException e) {
136             LOG.trace("Failed to normalize " + address + ": " + ExceptionUtils.getStackTrace(e));
137         }
138         return address;
139     }
140
141     public static LispAddressContainer normalize(LispAddressContainer address) {
142         if (address.getAddress() instanceof Ipv4) {
143             return normalize(address, ((Ipv4)address.getAddress()).getIpv4Address().getMask());
144         } else if (address.getAddress() instanceof Ipv6) {
145             return normalize(address, ((Ipv6)address.getAddress()).getIpv6Address().getMask());
146         } else if (address instanceof LcafSegmentAddress) {
147             LcafSegmentAddress segAddr = (LcafSegmentAddress) address;
148             LispAFIAddress afiAddr = LispAFIConvertor
149                     .toAFIfromPrimitive(segAddr.getAddress().getPrimitiveAddress());
150             short mask = getMaskForAfiAddress(afiAddr);
151             if (mask == 0) {
152                 return address;
153             }
154             Address normalizedAddr = new AddressBuilder().setPrimitiveAddress(
155                     LispAFIConvertor.toPrimitive(normalize(afiAddr, mask))).build();
156             return new LispAddressContainerBuilder().setAddress(
157                     new LcafSegmentBuilder().setLcafSegmentAddr(
158                             new LcafSegmentAddrBuilder(segAddr).setAddress(normalizedAddr).build()).build())
159                     .build();
160         }
161         return address;
162     }
163
164     private static InetAddress normalizeIP(InetAddress address, int mask) throws UnknownHostException {
165         ByteBuffer byteRepresentation = ByteBuffer.wrap(address.getAddress());
166         byte b = (byte) 0xff;
167         for (int i = 0; i < byteRepresentation.array().length; i++) {
168             if (mask >= 8)
169                 byteRepresentation.put(i, (byte) (b & byteRepresentation.get(i)));
170
171             else if (mask > 0) {
172                 byteRepresentation.put(i, (byte) ((byte) (b << (8 - mask)) & byteRepresentation.get(i)));
173             } else {
174                 byteRepresentation.put(i, (byte) (0 & byteRepresentation.get(i)));
175             }
176
177             mask -= 8;
178         }
179         return InetAddress.getByAddress(byteRepresentation.array());
180     }
181
182     public static String normalizeIPString(String addr, int mask) {
183         short afi = getIpAfiForString(addr);
184         try {
185             if (afi == 1) {
186                 return normalizeIP(Inet4Address.getByName(addr), mask).getHostAddress();
187             } else if (afi == 2) {
188                 return normalizeIP(Inet6Address.getByName(addr), mask).getHostAddress();
189             } else {
190                 LOG.debug("The string {} is not a valid IP address!", addr);
191                 return null;
192             }
193         } catch (Exception e){
194             LOG.trace("Failed to normalize " + addr + ": " + ExceptionUtils.getStackTrace(e));
195         }
196         return null;
197     }
198
199     public static int getMaxMask(LispAFIAddress address) {
200         if (address instanceof Ipv4Address) {
201             return 32;
202         }
203         if (address instanceof Ipv6Address) {
204             return 128;
205         }
206         return -1;
207     }
208
209     public static byte getMaxMaskForAfi(int afi) {
210         if (afi == 1) {
211             return (byte) 32;
212         } else if (afi == 2) {
213             return (byte) 128;
214         } else {
215             return (byte) -1;
216         }
217     }
218
219     private static short getMaskForAfiAddress(LispAFIAddress addr) {
220         if (addr instanceof Ipv4Address) {
221             Short res = ((Ipv4Address) addr).getMask();
222             return (res != null) ? res.shortValue() : 32;
223         } else if (addr instanceof Ipv6Address) {
224             Short res = ((Ipv6Address) addr).getMask();
225             return (res != null) ? res.shortValue() : 128;
226         } else {
227             return 0;
228         }
229     }
230
231     public static short getMaskForAddress(LispAddressContainer addr) {
232         if (addr.getAddress() instanceof Ipv4) {
233             Short res = ((Ipv4)addr.getAddress()).getIpv4Address().getMask();
234             return (res != null) ? res.shortValue() : 32;
235         } else if (addr.getAddress() instanceof Ipv6) {
236             Short res = ((Ipv6)addr.getAddress()).getIpv6Address().getMask();
237             return (res != null) ? res.shortValue() : 128;
238         } else if (addr.getAddress() instanceof LcafSegmentAddress) {
239             return getMaskForAfiAddress(LispAFIConvertor.toAFIfromPrimitive(((LcafSegmentAddress) addr.getAddress())
240                     .getAddress().getPrimitiveAddress()));
241         }
242         return 0;
243     }
244
245     private static short getIpAfiForString(String addr) {
246         if(addr.matches("([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])") == true){
247             return 1;
248         }
249         else if(addr.matches("([0-9a-f]+)\\:([0-9a-f]+)\\:([0-9a-f]+)\\:([0-9a-f]+)\\:([0-9a-f]+)\\:([0-9a-f]+)\\:([0-9a-f]+)\\:([0-9a-f]+)") == true){
250             return 2;
251         }
252         return -1;
253     }
254
255     public static LispAddressContainer setMask(LispAddressContainer addr, int mask) {
256         if (addr instanceof LispIpv4Address) {
257             return new LispAddressContainerBuilder().setAddress(
258                     new Ipv4Builder().setIpv4Address(
259                             new Ipv4AddressBuilder((LispIpv4Address) addr).setMask((short) mask).build()).build())
260                     .build();
261
262         } else if (addr instanceof LispIpv6Address) {
263             return new LispAddressContainerBuilder().setAddress(
264                     new Ipv6Builder().setIpv6Address(
265                             new Ipv6AddressBuilder((LispIpv6Address) addr).setMask((short) mask).build()).build())
266                     .build();
267         } else if (addr instanceof LcafSegmentAddress) {
268             LispAddressContainer newAddr = setMask(LispAFIConvertor.toContainer(LispAFIConvertor.toAFIfromPrimitive(((LcafSegmentAddress) addr).getAddress().getPrimitiveAddress())), mask);
269             return new LispAddressContainerBuilder().setAddress(newAddr.getAddress()).build();
270         }
271         return addr;
272     }
273
274     public static LispAFIAddress setMask(LispAFIAddress addr, int mask) {
275         if (addr instanceof LispIpv4Address) {
276             return new Ipv4AddressBuilder().setIpv4Address(((LispIpv4Address) addr).getIpv4Address())
277                     .setAfi(addr.getAfi()).setMask((short)mask).build();
278         } else if (addr instanceof LispIpv6Address) {
279             return new Ipv6AddressBuilder().setIpv6Address(((LispIpv6Address) addr).getIpv6Address())
280                     .setAfi(addr.getAfi()).setMask((short)mask).build();
281         } else if (addr instanceof LcafSegmentAddress) {
282             LispAFIAddress afiAddr = LispAFIConvertor.toAFIfromPrimitive(((LcafSegmentAddress) addr).getAddress()
283                     .getPrimitiveAddress());
284             afiAddr = setMask(afiAddr, mask);
285             return new LcafSegmentAddrBuilder((LcafSegmentAddress) addr).setAddress(
286                     new AddressBuilder().setPrimitiveAddress(LispAFIConvertor.toPrimitive(afiAddr)).build()).build();
287         }
288         return addr;
289     }
290
291     public static LispAFIAddress setMaskSourceDest(LispAFIAddress addr, int srcMask, int dstMask) {
292         DstAddress dst = LcafSourceDestHelper.getDstAddress(addr);
293         LispAFIAddress dstAfi = LispAFIConvertor.toAFIfromPrimitive(dst.getPrimitiveAddress());
294         DstAddress newDst = new DstAddressBuilder(dst).setPrimitiveAddress(LispAFIConvertor.toPrimitive(setMask(dstAfi, dstMask))).build();
295         SrcAddress src = LcafSourceDestHelper.getSrcAddress(addr);
296         LispAFIAddress srcAfi = LispAFIConvertor.toAFIfromPrimitive(src.getPrimitiveAddress());
297         SrcAddress newSrc = new SrcAddressBuilder(src).setPrimitiveAddress(LispAFIConvertor.toPrimitive(setMask(srcAfi, srcMask))).build();
298         return new LcafSourceDestAddrBuilder((LcafSourceDestAddress)addr).setDstAddress(newDst).setSrcAddress(newSrc).build();
299     }
300
301     public static LispAddressContainer setMaskSourceDest(LispAddressContainer addr, int srcMask, int dstMask) {
302         return new LispAddressContainerBuilder().setAddress(
303                 new LcafSourceDestBuilder((LcafSourceDest) addr.getAddress()).setLcafSourceDestAddr(
304                         (LcafSourceDestAddr) setMaskSourceDest(
305                                 ((LcafSourceDest) addr.getAddress()).getLcafSourceDestAddr(), srcMask, dstMask))
306                         .build()).build();
307     }
308 }