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      */
Network()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      */
Network(IPAddress addr)57     public Network(IPAddress addr) {
58 	initialize(addr);
59     }
60 
61     // Common initialization routine
initialize(IPAddress addr)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      */
Network(String addr)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      */
Network(String addr, int mask)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      */
Network(IPAddress addr, IPAddress mask)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      */
Network(String addr, String mask)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      */
getAddress()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      */
getNetworkNumber()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      */
getMask()180     public IPAddress getMask() {
181 	return netmask;
182     }
183 
184     /**
185      * Set the subnet mask.
186      * @param mask The subnet mask.
187      */
setMask(IPAddress mask)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      */
containsAddress(IPAddress addr)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      */
getBroadcastAddress()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      */
equals(Object obj)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 
toString()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      */
compareTo(Object o)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 }
266