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
1.5.1