blob: c2511a73a7313a9ec4c9aecd6e06041fed94fbad [file] [log] [blame]
Michael Hanlc31d09f2015-09-25 12:40:59 +02001package de.ids_mannheim.korap.utils;
2
3import java.net.Inet4Address;
4import java.net.InetAddress;
5import java.net.UnknownHostException;
6
7/**
8 * User: hanl
9 * Date: 9/13/13
10 * Time: 2:25 PM
Michael Hanl8abaf9e2016-05-23 16:46:35 +020011 *
Michael Hanlc31d09f2015-09-25 12:40:59 +020012 * currently only supports IPv4!
Michael Hanl8abaf9e2016-05-23 16:46:35 +020013 *
Michael Hanlc31d09f2015-09-25 12:40:59 +020014 */
15// todo: integrate to gerrit
16public class IPNetMask {
17
18 private final Inet4Address i4addr;
19 private final byte maskCtr;
20
21 private final int addrInt;
22 private final int maskInt;
23
24 private static final int default_mask = 16;
25
Michael Hanl8abaf9e2016-05-23 16:46:35 +020026
27 private IPNetMask (Inet4Address i4addr, byte mask) {
Michael Hanlc31d09f2015-09-25 12:40:59 +020028 this.i4addr = i4addr;
29 this.maskCtr = mask;
30
31 this.addrInt = addrToInt(i4addr);
32 this.maskInt = ~((1 << (32 - maskCtr)) - 1);
33 }
34
Michael Hanl8abaf9e2016-05-23 16:46:35 +020035
Michael Hanlc31d09f2015-09-25 12:40:59 +020036 /**
37 * IPNetMask factory method.
Michael Hanl8abaf9e2016-05-23 16:46:35 +020038 *
39 * @param addrSlashMask
40 * IP/Mask String in format "nnn.nnn.nnn.nnn/mask". If
41 * the "/mask" is omitted, "/32" (just the single
42 * address) is assumed.
Michael Hanlc31d09f2015-09-25 12:40:59 +020043 * @return a new IPNetMask
Michael Hanl8abaf9e2016-05-23 16:46:35 +020044 * @throws UnknownHostException
45 * if address part cannot be parsed by
46 * InetAddress
Michael Hanlc31d09f2015-09-25 12:40:59 +020047 */
Michael Hanl8abaf9e2016-05-23 16:46:35 +020048 public static IPNetMask getIPMask (String addrSlashMask)
Michael Hanlc31d09f2015-09-25 12:40:59 +020049 throws UnknownHostException {
50 int pos = addrSlashMask.indexOf('/');
51 String addr;
52 byte maskCtr;
53 if (pos == -1) {
54 addr = addrSlashMask;
55 maskCtr = default_mask;
Michael Hanl8abaf9e2016-05-23 16:46:35 +020056 }
57 else {
Michael Hanlc31d09f2015-09-25 12:40:59 +020058 addr = addrSlashMask.substring(0, pos);
59 maskCtr = Byte.parseByte(addrSlashMask.substring(pos + 1));
60 }
61
Michael Hanl8abaf9e2016-05-23 16:46:35 +020062 return new IPNetMask((Inet4Address) InetAddress.getByName(addr),
63 maskCtr);
Michael Hanlc31d09f2015-09-25 12:40:59 +020064 }
65
Michael Hanl8abaf9e2016-05-23 16:46:35 +020066
Michael Hanlc31d09f2015-09-25 12:40:59 +020067 /**
68 * Test given IPv4 address against this IPNetMask object.
Michael Hanl8abaf9e2016-05-23 16:46:35 +020069 *
70 * @param testAddr
71 * address to isSystem.
Michael Hanlc31d09f2015-09-25 12:40:59 +020072 * @return true if address is in the IP Mask range, false if not.
73 */
Michael Hanl8abaf9e2016-05-23 16:46:35 +020074 public boolean matches (Inet4Address testAddr) {
Michael Hanlc31d09f2015-09-25 12:40:59 +020075 int testAddrInt = addrToInt(testAddr);
76 return ((addrInt & maskInt) == (testAddrInt & maskInt));
77 }
78
Michael Hanl8abaf9e2016-05-23 16:46:35 +020079
Michael Hanlc31d09f2015-09-25 12:40:59 +020080 /**
81 * Convenience method that converts String host to IPv4 address.
Michael Hanl8abaf9e2016-05-23 16:46:35 +020082 *
83 * @param addr
84 * IP address to match in nnn.nnn.nnn.nnn format or
85 * hostname.
Michael Hanlc31d09f2015-09-25 12:40:59 +020086 * @return true if address is in the IP Mask range, false if not.
Michael Hanl8abaf9e2016-05-23 16:46:35 +020087 * @throws UnknownHostException
88 * if the string cannot be decoded.
Michael Hanlc31d09f2015-09-25 12:40:59 +020089 */
Michael Hanl8abaf9e2016-05-23 16:46:35 +020090 public boolean matches (String addr) throws UnknownHostException {
Michael Hanlc31d09f2015-09-25 12:40:59 +020091 return matches((Inet4Address) InetAddress.getByName(addr));
92 }
93
Michael Hanl8abaf9e2016-05-23 16:46:35 +020094
Michael Hanlc31d09f2015-09-25 12:40:59 +020095 /**
96 * Converts IPv4 address to integer representation.
97 */
Michael Hanl8abaf9e2016-05-23 16:46:35 +020098 private int addrToInt (Inet4Address i4addr) {
Michael Hanlc31d09f2015-09-25 12:40:59 +020099 byte[] ba = i4addr.getAddress();
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200100 return (ba[0] << 24) | ((ba[1] & 0xFF) << 16) | ((ba[2] & 0xFF) << 8)
Michael Hanlc31d09f2015-09-25 12:40:59 +0200101 | (ba[3] & 0xFF);
102 }
103
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200104
Michael Hanlc31d09f2015-09-25 12:40:59 +0200105 @Override
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200106 public String toString () {
Michael Hanlc31d09f2015-09-25 12:40:59 +0200107 return i4addr.getHostAddress() + "/" + maskCtr;
108 }
109
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200110
Michael Hanlc31d09f2015-09-25 12:40:59 +0200111 @Override
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200112 public boolean equals (Object obj) {
Michael Hanlc31d09f2015-09-25 12:40:59 +0200113 if (obj == null)
114 return false;
115 if (getClass() != obj.getClass())
116 return false;
117 final IPNetMask that = (IPNetMask) obj;
118 return (this.addrInt == that.addrInt && this.maskInt == that.maskInt);
119 }
120
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200121
Michael Hanlc31d09f2015-09-25 12:40:59 +0200122 @Override
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200123 public int hashCode () {
Michael Hanlc31d09f2015-09-25 12:40:59 +0200124 return this.maskInt + this.addrInt;
125 }
126
127}