subnet_calculator.cpp

Go to the documentation of this file.
00001 #ifndef SUBNET_CALCULATOR_IMPLEMENTATION_FILE
00002 #define SUBNET_CALCULATOR_IMPLEMENTATION_FILE
00003 
00004 /*****************************************************************************\
00005 *                                                                             *
00006 *  Name   : subnet_calculator                                                 *
00007 *  Author : Chris Koeritz                                                     *
00008 *                                                                             *
00009 *******************************************************************************
00010 * Copyright (c) 1997-$now By Author.  This program is free software; you can  *
00011 * redistribute it and/or modify it under the terms of the GNU General Public  *
00012 * License as published by the Free Software Foundation; either version 2 of   *
00013 * the License or (at your option) any later version.  This is online at:      *
00014 *     http://www.fsf.org/copyleft/gpl.html                                    *
00015 * Please send any updates to: fred@gruntose.com                               *
00016 \*****************************************************************************/
00017 
00018 //hmmm: this class only handles 32 bit (4 byte) internet addresses.  it should
00019 //      use an arbitrary length integer object to overcome differences in the
00020 //      sizes of internet addresses.
00021 //      really we should just start using the machine uid underneath...
00022 
00023 #include "subnet_calculator.h"
00024 
00025 #include <basis/function.h>
00026 #include <basis/istring.h>
00027 
00028 subnet_calculator::subnet_calculator(const istring &mask, const istring &samp)
00029 : _valid(false),
00030   _subnet_mask(new istring(mask)),
00031   _ip_address(new istring(samp)),
00032   _low_end(new istring("")),
00033   _high_end(new istring(""))
00034 { calculate(); }
00035 
00036 subnet_calculator::~subnet_calculator()
00037 {
00038   WHACK(_subnet_mask);
00039   WHACK(_ip_address);
00040   WHACK(_low_end);
00041   WHACK(_high_end);
00042   _valid = false;
00043 }
00044 
00045 const istring &subnet_calculator::subnet_mask() const { return *_subnet_mask; }
00046 
00047 const istring &subnet_calculator::ip_address() const { return *_ip_address; }
00048 
00049 void subnet_calculator::subnet_mask(const istring &new_mask)
00050 {
00051   _valid = false;
00052   *_subnet_mask = new_mask;
00053 }
00054 
00055 void subnet_calculator::ip_address(const istring &new_address)
00056 {
00057   _valid = false;
00058   *_ip_address = new_address;
00059 }
00060 
00061 const istring &subnet_calculator::low_end()
00062 {
00063   calculate();
00064   return *_low_end;
00065 }
00066 
00067 const istring &subnet_calculator::high_end()
00068 {
00069   calculate();
00070   return *_high_end;
00071 }
00072 
00073 istring subnet_calculator::convert(u_int num_format)
00074 {
00075   istring to_return;
00076   u_int temp_num = num_format;
00077   for (int i = 0; i < 4; i++) {
00078     if (to_return.t())
00079       to_return = istring(".") + to_return;
00080     // shave a byte off for inclusion in the string.
00081     u_int new_byte = temp_num % 256;
00082     temp_num >>= 8;
00083     to_return = istring(istring::SPRINTF, "%d", new_byte) + to_return;
00084   }
00085   return to_return;
00086 }
00087 
00088 u_int subnet_calculator::convert(const istring &ip_format)
00089 {
00090   u_int to_return = 0;
00091   istring ip_temp = ip_format;
00092   for (int i = 0; i < 3; i++) {
00093     int indy = ip_temp.find(".");
00094     if (indy < 0) return to_return;
00095     istring this_piece = ip_temp.substring(0, indy - 1);
00096     to_return <<= 8;
00097     to_return += this_piece.convert(0);
00098     ip_temp.zap(0, indy);
00099   }
00100 
00101   if (ip_temp.length()) {
00102     to_return <<= 8;
00103     to_return += ip_temp.convert(0);
00104   }
00105 
00106   return to_return;
00107 }
00108 
00109 void subnet_calculator::calculate()
00110 {
00111   if (valid()) return;  // already valid.
00112 
00113   u_int ip = convert(*_ip_address);
00114   u_int sub = convert(*_subnet_mask);
00115 
00116   u_int low_end = sub & ip;
00117     // strips off the host part of the ip address and leaves just the network
00118     // component that comes from the ip address.
00119 
00120   u_int temp_sub = sub;
00121   int bits_to_add = 0;
00122   // we shift the subnet mask until we find it's first lowest order "1" bit.
00123   // this tells us how many bits are in the host portion (unless the mask is
00124   // zero, in which case the host is all of the bits).
00125   while (temp_sub && !(temp_sub % 2)) {
00126     temp_sub >>= 1;  // shift off a bit.
00127     bits_to_add++;  // record that the place we were at had a zero bit.
00128   }
00129   if (!sub) bits_to_add = 32;
00130     // account for a blank subnet mask, meaning there is no network and all
00131     // bits are used for host addresses.
00132   u_int add_in_for_bcast = 0;
00133     // the part added in to make a broadcast address.  this is all ones.
00134   for (int i = 0; i < bits_to_add; i++) {
00135     add_in_for_bcast <<= 1;  // shift the existing add_in to the left.
00136     add_in_for_bcast++;  // make a new one bit in the ones place.
00137   }
00138 
00139   u_int high_end = low_end + add_in_for_bcast;
00140 
00141   *_low_end = convert(low_end);
00142   *_high_end = convert(high_end);
00143   _valid = true;
00144 }
00145 
00146 
00147 #endif //SUBNET_CALCULATOR_IMPLEMENTATION_FILE
00148 

Generated on Fri Nov 21 04:29:17 2008 for HOOPLE Libraries by  doxygen 1.5.1