1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * ident "%Z%%M% %I% %E% SMI"
24 *
25 * Copyright 1998-2002 Sun Microsystems, Inc. All rights reserved.
26 * Use is subject to license terms.
27 */
28 package com.sun.dhcpmgr.data;
29
30 import java.io.Serializable;
31 import java.util.StringTokenizer;
32 import java.text.MessageFormat;
33
34 /**
35 * A representation of an IP network from DHCP's point of view; we're
36 * primarily interested in the address and subnet mask.
37 */
38 public class Network implements Serializable, Comparable {
39 private IPAddress address;
40 private IPAddress netmask;
41
42 // Serialization id for this class
43 static final long serialVersionUID = 7221738570228102243L;
44
45 /**
46 * Construct an empty network object
47 */
48 public Network() {
49 address = new IPAddress();
50 netmask = new IPAddress();
51 }
52
53 /**
54 * Construct a network with the supplied address and a default mask
55 * @param addr The IP address of the network
56 */
57 public Network(IPAddress addr) {
58 initialize(addr);
59 }
60
61 // Common initialization routine
62 private void initialize(IPAddress addr) {
63 address = addr;
64 // Initialize a default netmask based on address class
65 byte [] b = address.getAddress();
66 int msb = (int)b[0] & 0xff;
67 try {
68 if (msb < 128) {
69 netmask = new IPAddress("255.0.0.0");
70 } else if (msb < 192) {
71 netmask = new IPAddress("255.255.0.0");
72 } else {
73 netmask = new IPAddress("255.255.255.0");
74 }
75 } catch (ValidationException e) {
76 // This shouldn't happen, above masks are all valid IP addrs
77 }
78 }
79
80 /**
81 * Construct a network with the supplied address.
82 * @param addr The IP address of the network.
83 */
84 public Network(String addr) throws ValidationException {
85 try {
86 initialize(new IPAddress(addr));
87 } catch (ValidationException e) {
88 Object [] args = new Object[1];
89 args[0] = addr;
90 MessageFormat form = new MessageFormat(
91 ResourceStrings.getString("invalid_network"));
92 String msg = form.format(args);
93 throw new ValidationException(msg);
94 }
95 }
96
97 /**
98 * Construct a network with the supplied address and subnet mask
99 * @param addr The IP address of the network as a <code>String</code>
100 * @param mask The subnet mask as an <code>int</code>
101 */
102 public Network(String addr, int mask) throws ValidationException {
103 try {
104 address = new IPAddress(addr);
105 } catch (ValidationException e) {
106 Object [] args = new Object[1];
107 args[0] = addr;
108 MessageFormat form = new MessageFormat(
109 ResourceStrings.getString("invalid_network"));
110 String msg = form.format(args);
111 throw new ValidationException(msg);
112 }
113
114 netmask = new IPAddress(mask);
115 }
116
117 /**
118 * Construct a network with the supplied address and subnet mask.
119 * @param addr The IP address as an <code>IPAddress</code>
120 * @param mask The subnet mask as an <code>IPAddress</code>
121 */
122 public Network(IPAddress addr, IPAddress mask) {
123 address = addr;
124 netmask = mask;
125 }
126
127 /**
128 * Construct a network with the supplied address and subnet mask.
129 * @param addr The IP address as a dotted decimal <code>String</code>
130 * @param mask The subnet mask as a dotted decimal <code>String</code>
131 */
132 public Network(String addr, String mask) throws ValidationException {
133 try {
134 address = new IPAddress(addr);
135 } catch (ValidationException e) {
136 Object [] args = new Object[1];
137 args[0] = addr;
138 MessageFormat form = new MessageFormat(
139 ResourceStrings.getString("invalid_network"));
140 String msg = form.format(args);
141 throw new ValidationException(msg);
142 }
143
144 try {
145 netmask = new IPAddress(mask);
146 } catch (ValidationException e) {
147 Object [] args = new Object[1];
148 args[0] = mask;
149 MessageFormat form = new MessageFormat(
150 ResourceStrings.getString("invalid_netmask"));
151 String msg = form.format(args);
152 throw new ValidationException(msg);
153 }
154 }
155
156 /**
157 * @return The IP address of the network
158 */
159 public IPAddress getAddress() {
160 return address;
161 }
162
163 /**
164 * Return the actual network number, which is the product of applying
165 * the subnet mask to the address supplied.
166 * @return The network number as an <code>IPAddress</code>
167 */
168 public IPAddress getNetworkNumber() {
169 // If netmask is not set then ignore it and return address raw
170 if (netmask.intValue() == 0) {
171 return address;
172 } else {
173 return new IPAddress(address.intValue() & netmask.intValue());
174 }
175 }
176
177 /**
178 * @return The subnet mask of the network
179 */
180 public IPAddress getMask() {
181 return netmask;
182 }
183
184 /**
185 * Set the subnet mask.
186 * @param mask The subnet mask.
187 */
188 public void setMask(IPAddress mask) {
189 netmask = mask;
190 }
191
192 /**
193 * Do the math to evaluate whether an address is part of this network.
194 * @param addr The IP address to evaluate
195 * @return <code>true</code> if the address is on this network,
196 * <code>false</code> if not.
197 */
198 public boolean containsAddress(IPAddress addr) {
199 return ((addr.intValue() & netmask.intValue())
200 == (address.intValue() & netmask.intValue()));
201 }
202
203 /**
204 * Compute the broadcast address for this network and return it.
205 * @return a string representation of the broadcast address.
206 */
207 public String getBroadcastAddress() {
208
209 byte [] netBytes = getAddress().getAddress();
210 byte [] maskBytes = getMask().getAddress();
211 StringBuffer buf = new StringBuffer();
212 for (int i = 0; i < netBytes.length; ++i) {
213 int b = (netBytes[i] | ~maskBytes[i]) & 0xff;
214 if (buf.length() != 0) {
215 buf.append('.');
216 }
217 buf.append(b);
218 }
219
220 return (buf.toString());
221
222 } // getBroadcastAddress
223
224 /**
225 * Compare against another network object for equality.
226 * @param obj The network to compare against.
227 * @return <code>true</code> if the networks have the same network number
228 */
229 public boolean equals(Object obj) {
230 // If object passed isn't of same type, always false.
231 if (!(obj instanceof Network)) {
232 return false;
233 }
234 return getNetworkNumber().equals(((Network)obj).getNetworkNumber());
235 }
236
237 public String toString() {
238 return getNetworkNumber().toString();
239 }
240
241 /**
242 * Perform comparisons to another Network instance. This is used
243 * for sorting a list of network tables.
244 * @param o A <code>Network</code> to compare against.
245 * @return 0 if the objects have the same address,
246 * a negative number if this record has a lower IP address than the
247 * supplied record, a positive number if this record has a higher IP
248 * address than the supplied record.
249 */
250 public int compareTo(Object o) {
251
252 Network n = (Network)o;
253 long result = getNetworkNumber().getBinaryAddress() -
254 n.getNetworkNumber().getBinaryAddress();
255
256 if (result < 0) {
257 return (-1);
258 } else if (result > 0) {
259 return (1);
260 } else {
261 return (0);
262 }
263 }
264
265 }