IPAddress.java revision e6bf3e8dfa2804891a82075cb469b736321b4827
1package org.bouncycastle.util;
2
3public class IPAddress
4{
5    /**
6     * Validate the given IPv4 or IPv6 address.
7     *
8     * @param address the IP address as a String.
9     *
10     * @return true if a valid address, false otherwise
11     */
12    public static boolean isValid(
13        String address)
14    {
15        return isValidIPv4(address) || isValidIPv6(address);
16    }
17
18    /**
19     * Validate the given IPv4 or IPv6 address and netmask.
20     *
21     * @param address the IP address as a String.
22     *
23     * @return true if a valid address with netmask, false otherwise
24     */
25    public static boolean isValidWithNetMask(
26        String address)
27    {
28        return isValidIPv4WithNetmask(address) || isValidIPv6WithNetmask(address);
29    }
30
31    /**
32     * Validate the given IPv4 address.
33     *
34     * @param address the IP address as a String.
35     *
36     * @return true if a valid IPv4 address, false otherwise
37     */
38    public static boolean isValidIPv4(
39        String address)
40    {
41        if (address.length() == 0)
42        {
43            return false;
44        }
45
46        int octet;
47        int octets = 0;
48
49        String temp = address+".";
50
51        int pos;
52        int start = 0;
53        while (start < temp.length()
54            && (pos = temp.indexOf('.', start)) > start)
55        {
56            if (octets == 4)
57            {
58                return false;
59            }
60            try
61            {
62                octet = Integer.parseInt(temp.substring(start, pos));
63            }
64            catch (NumberFormatException ex)
65            {
66                return false;
67            }
68            if (octet < 0 || octet > 255)
69            {
70                return false;
71            }
72            start = pos + 1;
73            octets++;
74        }
75
76        return octets == 4;
77    }
78
79    public static boolean isValidIPv4WithNetmask(
80        String address)
81    {
82        int index = address.indexOf("/");
83        String mask = address.substring(index + 1);
84
85        return (index > 0) && isValidIPv4(address.substring(0, index))
86                           && (isValidIPv4(mask) || isMaskValue(mask, 32));
87    }
88
89    public static boolean isValidIPv6WithNetmask(
90        String address)
91    {
92        int index = address.indexOf("/");
93        String mask = address.substring(index + 1);
94
95        return (index > 0) && (isValidIPv6(address.substring(0, index))
96                           && (isValidIPv6(mask) || isMaskValue(mask, 128)));
97    }
98
99    private static boolean isMaskValue(String component, int size)
100    {
101        try
102        {
103            int value = Integer.parseInt(component);
104
105            return value >= 0 && value <= size;
106        }
107        catch (NumberFormatException e)
108        {
109            return false;
110        }
111    }
112
113    /**
114     * Validate the given IPv6 address.
115     *
116     * @param address the IP address as a String.
117     *
118     * @return true if a valid IPv4 address, false otherwise
119     */
120    public static boolean isValidIPv6(
121        String address)
122    {
123        if (address.length() == 0)
124        {
125            return false;
126        }
127
128        int octet;
129        int octets = 0;
130
131        String temp = address + ":";
132        boolean doubleColonFound = false;
133        int pos;
134        int start = 0;
135        while (start < temp.length()
136            && (pos = temp.indexOf(':', start)) >= start)
137        {
138            if (octets == 8)
139            {
140                return false;
141            }
142
143            if (start != pos)
144            {
145                String value = temp.substring(start, pos);
146
147                if (pos == (temp.length() - 1) && value.indexOf('.') > 0)
148                {
149                    if (!isValidIPv4(value))
150                    {
151                        return false;
152                    }
153
154                    octets++; // add an extra one as address covers 2 words.
155                }
156                else
157                {
158                    try
159                    {
160                        octet = Integer.parseInt(temp.substring(start, pos), 16);
161                    }
162                    catch (NumberFormatException ex)
163                    {
164                        return false;
165                    }
166                    if (octet < 0 || octet > 0xffff)
167                    {
168                        return false;
169                    }
170                }
171            }
172            else
173            {
174                if (pos != 1 && pos != temp.length() - 1 && doubleColonFound)
175                {
176                    return false;
177                }
178                doubleColonFound = true;
179            }
180            start = pos + 1;
181            octets++;
182        }
183
184        return octets == 8 || doubleColonFound;
185    }
186}
187
188
189