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 }