feisty meow concerns codebase  2.140
subnet_calculator.cpp
Go to the documentation of this file.
1 
2 
3 
4 /*****************************************************************************\
5 * *
6 * Name : subnet_calculator *
7 * Author : Chris Koeritz *
8 * *
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 \*****************************************************************************/
17 
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...
22 
23 #include "subnet_calculator.h"
24 
25 #include <basis/functions.h>
26 #include <basis/astring.h>
27 
28 using namespace basis;
29 
30 namespace sockets {
31 
32 subnet_calculator::subnet_calculator(const astring &mask, const astring &samp)
33 : _valid(false),
34  _subnet_mask(new astring(mask)),
35  _ip_address(new astring(samp)),
36  _low_end(new astring("")),
37  _high_end(new astring(""))
38 { calculate(); }
39 
41 {
42  WHACK(_subnet_mask);
43  WHACK(_ip_address);
44  WHACK(_low_end);
45  WHACK(_high_end);
46  _valid = false;
47 }
48 
49 const astring &subnet_calculator::subnet_mask() const { return *_subnet_mask; }
50 
51 const astring &subnet_calculator::ip_address() const { return *_ip_address; }
52 
54 {
55  _valid = false;
56  *_subnet_mask = new_mask;
57 }
58 
59 void subnet_calculator::ip_address(const astring &new_address)
60 {
61  _valid = false;
62  *_ip_address = new_address;
63 }
64 
66 {
67  calculate();
68  return *_low_end;
69 }
70 
72 {
73  calculate();
74  return *_high_end;
75 }
76 
78 {
79  astring to_return;
80  basis::un_int temp_num = num_format;
81  for (int i = 0; i < 4; i++) {
82  if (to_return.t())
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;
86  temp_num >>= 8;
87  to_return = astring(astring::SPRINTF, "%d", new_byte) + to_return;
88  }
89  return to_return;
90 }
91 
93 {
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);
100  to_return <<= 8;
101  to_return += this_piece.convert(0);
102  ip_temp.zap(0, indy);
103  }
104 
105  if (ip_temp.length()) {
106  to_return <<= 8;
107  to_return += ip_temp.convert(0);
108  }
109 
110  return to_return;
111 }
112 
113 void subnet_calculator::calculate()
114 {
115  if (valid()) return; // already valid.
116 
117  basis::un_int ip = convert(*_ip_address);
118  basis::un_int sub = convert(*_subnet_mask);
119 
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.
123 
124  basis::un_int temp_sub = sub;
125  int bits_to_add = 0;
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.
132  }
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.
141  }
142 
143  basis::un_int high_end = low_end + add_in_for_bcast;
144 
145  *_low_end = convert(low_end);
146  *_high_end = convert(high_end);
147  _valid = true;
148 }
149 
150 } //namespace.
151 
152 
Provides a dynamically resizable ASCII character string.
Definition: astring.h:35
bool t() const
t() is a shortcut for the string being "true", as in non-empty.
Definition: astring.h:97
int convert(int default_value) const
Converts the string into a corresponding integer.
Definition: astring.cpp:757
virtual void zap(int start, int end)
Deletes the characters between "start" and "end" inclusively.
Definition: astring.cpp:521
bool substring(astring &target, int start, int end) const
a version that stores the substring in an existing "target" string.
Definition: astring.cpp:865
int length() const
Returns the current length of the string.
Definition: astring.cpp:132
int find(char to_find, int position=0, bool reverse=false) const
Locates "to_find" in "this".
Definition: astring.cpp:574
const basis::astring & low_end()
const basis::astring & high_end()
basis::astring convert(basis::un_int num_format)
const basis::astring & ip_address() const
const basis::astring & subnet_mask() const
The guards collection helps in testing preconditions and reporting errors.
Definition: array.h:30
void WHACK(contents *&ptr)
deletion with clearing of the pointer.
Definition: functions.h:121
unsigned int un_int
Abbreviated name for unsigned integers.
Definition: definitions.h:62
Provides access to the operating system's socket methods.
Definition: base_address.h:26