4 /*****************************************************************************\
6 * Name : subnet_calculator *
7 * Author : Chris Koeritz *
9 *******************************************************************************
10 * Copyright (c) 1997-$now By Author. This program is free software; you can *
11 * redistribute it and/or modify it under the terms of the GNU General Public *
12 * License as published by the Free Software Foundation; either version 2 of *
13 * the License or (at your option) any later version. This is online at: *
14 * http://www.fsf.org/copyleft/gpl.html *
15 * Please send any updates to: fred@gruntose.com *
16 \*****************************************************************************/
18 //hmmm: this class only handles 32 bit (4 byte) internet addresses. it should
19 // use an arbitrary length integer object to overcome differences in the
20 // sizes of internet addresses.
21 // really we should just start using the machine uid underneath...
23 #include "subnet_calculator.h"
25 #include <basis/functions.h>
26 #include <basis/astring.h>
28 using namespace basis;
32 subnet_calculator::subnet_calculator(const astring &mask, const astring &samp)
34 _subnet_mask(new astring(mask)),
35 _ip_address(new astring(samp)),
36 _low_end(new astring("")),
37 _high_end(new astring(""))
40 subnet_calculator::~subnet_calculator()
49 const astring &subnet_calculator::subnet_mask() const { return *_subnet_mask; }
51 const astring &subnet_calculator::ip_address() const { return *_ip_address; }
53 void subnet_calculator::subnet_mask(const astring &new_mask)
56 *_subnet_mask = new_mask;
59 void subnet_calculator::ip_address(const astring &new_address)
62 *_ip_address = new_address;
65 const astring &subnet_calculator::low_end()
71 const astring &subnet_calculator::high_end()
77 astring subnet_calculator::convert(basis::un_int num_format)
80 basis::un_int temp_num = num_format;
81 for (int i = 0; i < 4; i++) {
83 to_return = astring(".") + to_return;
84 // shave a byte off for inclusion in the string.
85 basis::un_int new_byte = temp_num % 256;
87 to_return = astring(astring::SPRINTF, "%d", new_byte) + to_return;
92 un_int subnet_calculator::convert(const astring &ip_format)
94 basis::un_int to_return = 0;
95 astring ip_temp = ip_format;
96 for (int i = 0; i < 3; i++) {
97 int indy = ip_temp.find(".");
98 if (indy < 0) return to_return;
99 astring this_piece = ip_temp.substring(0, indy - 1);
101 to_return += this_piece.convert(0);
102 ip_temp.zap(0, indy);
105 if (ip_temp.length()) {
107 to_return += ip_temp.convert(0);
113 void subnet_calculator::calculate()
115 if (valid()) return; // already valid.
117 basis::un_int ip = convert(*_ip_address);
118 basis::un_int sub = convert(*_subnet_mask);
120 basis::un_int low_end = sub & ip;
121 // strips off the host part of the ip address and leaves just the network
122 // component that comes from the ip address.
124 basis::un_int temp_sub = sub;
126 // we shift the subnet mask until we find it's first lowest order "1" bit.
127 // this tells us how many bits are in the host portion (unless the mask is
128 // zero, in which case the host is all of the bits).
129 while (temp_sub && !(temp_sub % 2)) {
130 temp_sub >>= 1; // shift off a bit.
131 bits_to_add++; // record that the place we were at had a zero bit.
133 if (!sub) bits_to_add = 32;
134 // account for a blank subnet mask, meaning there is no network and all
135 // bits are used for host addresses.
136 basis::un_int add_in_for_bcast = 0;
137 // the part added in to make a broadcast address. this is all ones.
138 for (int i = 0; i < bits_to_add; i++) {
139 add_in_for_bcast <<= 1; // shift the existing add_in to the left.
140 add_in_for_bcast++; // make a new one bit in the ones place.
143 basis::un_int high_end = low_end + add_in_for_bcast;
145 *_low_end = convert(low_end);
146 *_high_end = convert(high_end);