fixes for several logical bugs
[groupbasedpolicy.git] / groupbasedpolicy / src / main / java / org / opendaylight / groupbasedpolicy / util / NetUtils.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, 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
9 package org.opendaylight.groupbasedpolicy.util;
10
11 import javax.annotation.Nonnull;
12 import javax.annotation.Nullable;
13
14 import org.apache.commons.net.util.SubnetUtils;
15 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
16 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
17 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
18
19 import com.google.common.base.Strings;
20 import com.googlecode.ipv6.IPv6NetworkMask;
21
22 public final class NetUtils {
23
24     /**
25      * Extract prefix length from prefix form
26      * Works for both IPv4 and IPv6
27      *
28      * @param prefix {@code String} to extract prefix length from
29      * @return prefix length as {@code int}
30      */
31     public static int getMaskFromPrefix(@Nullable String prefix) {
32         String newPrefix = Strings.nullToEmpty(prefix);
33         int slashIndex = newPrefix.indexOf("/");
34         if (slashIndex == -1) {
35             slashIndex = newPrefix.length() - 1;
36         }
37         return Integer.parseInt(newPrefix.substring(slashIndex + 1));
38     }
39
40     /**
41      * Extract IP adress from prefix form
42      * Works for both IPv4 and IPv6
43      *
44      * @param prefix {@code String} to extract IP address from
45      * @return IP address as a {@code String}
46      */
47     public static @Nonnull String getIpAddrFromPrefix(@Nullable String prefix) {
48         String newPrefix = Strings.nullToEmpty(prefix);
49         int slashIndex = newPrefix.indexOf("/");
50         if (slashIndex == -1) {
51             slashIndex = newPrefix.length();
52         }
53         return newPrefix.substring(0, slashIndex);
54     }
55
56     /**
57      * Mask IPv6 address from prefix with provided prefix length
58      *
59      * @param ipv6Prefix {@link Ipv6Prefix} to apply mask on
60      * @param ipv6MaskLength prefix length
61      * @return resulting network IP address as {@link Ipv6Address}
62      */
63     public static @Nullable Ipv6Address applyMaskOnIpv6Prefix(@Nullable Ipv6Prefix ipv6Prefix, int ipv6MaskLength) {
64         if (ipv6Prefix == null) {
65             return null;
66         }
67         return applyMaskOnIpv6Address(new Ipv6Address(getIpAddrFromPrefix(ipv6Prefix.getValue())), ipv6MaskLength);
68     }
69
70     /**
71      * Mask IPv6 address with provided prefix length
72      *
73      * @param ipv6Address {@link Ipv6Prefix} to apply mask on
74      * @param ipv6MaskLength prefix length
75      * @return resulting network address as {@link Ipv6Address}, {@code null} if provided address is null
76      */
77     public static @Nullable Ipv6Address applyMaskOnIpv6Address(@Nullable Ipv6Address ipv6Address, int ipv6MaskLength) {
78         if (ipv6Address == null) {
79             return null;
80         }
81         com.googlecode.ipv6.IPv6Address ip = com.googlecode.ipv6.IPv6Address.fromString(ipv6Address.getValue());
82         IPv6NetworkMask mask = IPv6NetworkMask.fromPrefixLength(ipv6MaskLength);
83         ip = ip.maskWithNetworkMask(mask);
84         return new Ipv6Address(ip.toString());
85     }
86
87     /**
88      * Check if two IpPrefixes represents same network. Must be identical in network address and prefix length.
89      * Works for both IPv4 and IPv6
90      *
91      * @param prefix1 {@link IpPrefix} to compare
92      * @param prefix2 {@link IpPrefix} to compare
93      * @return {@code true} if provided prefixes are identical, otherwise return {@code false}
94      */
95     public static boolean samePrefix(@Nullable IpPrefix prefix1, @Nullable IpPrefix prefix2) {
96         if (prefix1 == null || prefix2 == null) {
97             return false;
98         }
99         if (prefix1.getIpv4Prefix() != null && prefix2.getIpv4Prefix() != null) {
100             SubnetUtils fromPrefix1 = new SubnetUtils(prefix1.getIpv4Prefix().getValue());
101             SubnetUtils fromPrefix2 = new SubnetUtils(prefix2.getIpv4Prefix().getValue());
102             if (fromPrefix1.getInfo().getNetworkAddress().equals(fromPrefix2.getInfo().getNetworkAddress())
103                     && fromPrefix1.getInfo().getNetmask().equals(fromPrefix2.getInfo().getNetmask())) {
104                 return true;
105             }
106         } else if (prefix1.getIpv6Prefix() != null && prefix2.getIpv6Prefix() != null) {
107             int ipv6MaskLength1 = getMaskFromPrefix(prefix1.getIpv6Prefix().getValue());
108             int ipv6MaskLength2 = getMaskFromPrefix(prefix2.getIpv6Prefix().getValue());
109             if (ipv6MaskLength1 != ipv6MaskLength2) {
110                 return false;
111             }
112             Ipv6Address ipv6Network = applyMaskOnIpv6Prefix(prefix1.getIpv6Prefix(), ipv6MaskLength1);
113             Ipv6Address hostv6Network = applyMaskOnIpv6Prefix(prefix2.getIpv6Prefix(), ipv6MaskLength1);
114             if (ipv6Network.getValue().equals(hostv6Network.getValue())) {
115                 return true;
116             }
117         }
118         return false;
119     }
120 }