00001
00002
00003
00005
00006
00007
00008
00009
00010
00011
00012
00013
00015
00016 #include "internet_address.h"
00017 #include "machine_uid.h"
00018
00019 #include <basis/byte_array.h>
00020 #include <basis/functions.h>
00021 #include <basis/astring.h>
00022 #include <basis/mutex.h>
00023 #include <configuration/configurator.h>
00024 #include <configuration/variable_tokenizer.h>
00025 #include <loggers/program_wide_logger.h>
00026 #include <structures/static_memory_gremlin.h>
00027 #include <structures/string_table.h>
00028 #include <textual/parser_bits.h>
00029
00030 #include <stdio.h>
00031 #include <string.h>
00032
00033 using namespace basis;
00034 using namespace configuration;
00035 using namespace loggers;
00036 using namespace structures;
00037 using namespace textual;
00038
00039 namespace sockets {
00040
00041
00042
00043
00045
00046 #undef LOG
00047 #define LOG(to_print) CLASS_EMERGENCY_LOG(program_wide_logger::get(), to_print)
00048
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00082
00083
00084
00085 #define CAST_UP(type) \
00086 const type *temp = dynamic_cast<const type *>(&compare_in); \
00087 if (!temp) return false; \
00088 const type &to_compare = *temp;
00089
00091
00092 internet_address::internet_address() { fill(byte_array(), "", 0); }
00093
00094 internet_address::internet_address(const byte_array &ip,
00095 const astring &host, int port_in)
00096 { fill(ip, host, port_in); }
00097
00098
00099
00100
00101
00102 machine_uid internet_address::convert() const
00103 { return internet_machine_uid(hostname, byte_array(ADDRESS_SIZE, ip_address)); }
00104
00105 bool internet_address::ip_appropriate_number(const astring &to_check, int indy,
00106 astring &accum)
00107 {
00108
00109 accum.reset();
00110 for (int i = indy; (i < indy + 3) && (i < to_check.length()); i++) {
00111
00112 if (!parser_bits::is_numeric(to_check[i]) || (to_check[i] == '-') ) {
00113
00114
00115 if (i == indy) return false;
00116 else break;
00117 }
00118 accum += to_check[i];
00119 }
00120 if (!accum.length()) return false;
00121 int convert = accum.convert(-1);
00122 return (convert >= 0) && (convert <= 255);
00123 }
00124
00125
00126
00127 bool internet_address::has_ip_address(const astring &to_check,
00128 astring &ip_found)
00129 {
00130
00131 int nums_seen = 0;
00132 ip_found.reset();
00133 for (int i = 0; i < to_check.length(); i++) {
00134 bool hosed = false;
00135 astring num_found;
00136
00137 if (!ip_appropriate_number(to_check, i, num_found)) {
00138
00139 hosed = true;
00140 } else {
00141
00142
00143 nums_seen++;
00144 if (nums_seen >= 4) {
00145 ip_found += num_found;
00146 return true;
00147 }
00148
00149 int period_indy = to_check.find('.', i);
00150 if (negative(period_indy) || (period_indy > i + 3) ) hosed = true;
00151 else {
00152 for (int x = i; x < period_indy; x++) {
00153 if (!parser_bits::is_numeric(to_check[x]) || (to_check[x] == '-')) {
00154
00155 hosed = true;
00156 }
00157 }
00158 if (!hosed) {
00159 ip_found += to_check.substring(i, period_indy);
00160 i = period_indy;
00161 }
00162 }
00163 }
00164 if (hosed) {
00165 nums_seen = 0;
00166 ip_found.reset();
00167 }
00168 }
00169 return false;
00170 }
00171
00172 const abyte localhosts_bytes[] = { 127, 0, 0, 1 };
00173 SAFE_STATIC_CONST(byte_array, internet_address::localhost,
00174 (ADDRESS_SIZE, localhosts_bytes))
00175
00176 bool internet_address::is_localhost() const
00177 {
00178
00179 astring host = hostname;
00180 host.to_lower();
00181 if ( (host.equal_to("local")) || (host.equal_to("localhost")) )
00182 return true;
00183
00184
00185 for (int i = 0; i < ADDRESS_SIZE; i++) {
00186 if (ip_address[i] != localhost().get(i))
00187 return false;
00188 }
00189
00190 return true;
00191 }
00192
00193 astring internet_address::normalize_host() const
00194 {
00195
00196 astring remote = hostname;
00197 if (remote.t()) return remote;
00198
00199 byte_array ip_form(ADDRESS_SIZE, ip_address);
00200 remote = ip_address_text_form(ip_form);
00201 return remote;
00202 }
00203
00204 int internet_address::packed_size() const
00205 {
00206 return sizeof(port) +
00207 + sizeof(int) + ADDRESS_SIZE
00208 + sizeof(int) + MAXIMUM_HOSTNAME_LENGTH;
00209 }
00210
00211 void internet_address::pack(byte_array &packed_form) const
00212 {
00213 attach(packed_form, port);
00214 packed_form += byte_array(ADDRESS_SIZE, ip_address);
00215 packed_form += byte_array(MAXIMUM_HOSTNAME_LENGTH, (abyte *)hostname);
00216 }
00217
00218 bool internet_address::unpack(byte_array &packed_form)
00219 {
00220
00221 if (packed_form.length() < int(sizeof(port)) + ADDRESS_SIZE
00222 + MAXIMUM_HOSTNAME_LENGTH)
00223 return false;
00224 if (!detach(packed_form, port)) return false;
00225 packed_form.stuff(ADDRESS_SIZE, ip_address);
00226 packed_form.zap(0, ADDRESS_SIZE - 1);
00227 packed_form.stuff(MAXIMUM_HOSTNAME_LENGTH, (abyte *)hostname);
00228 packed_form.zap(0, MAXIMUM_HOSTNAME_LENGTH - 1);
00229 return true;
00230 }
00231
00232 void internet_address::fill(const byte_array &ip, const astring &host,
00233 int port_in)
00234 {
00235 port = port_in;
00236 int mini = minimum(int(ADDRESS_SIZE), ip.length());
00237 for (int i = 0; i < mini; i++) ip_address[i] = ip[i];
00238 for (int j = mini; j < ADDRESS_SIZE; j++) ip_address[j] = 0;
00239 hostname[0] = '\0';
00240 host.stuff(hostname, MAXIMUM_HOSTNAME_LENGTH - 1);
00241 }
00242
00243 base_address *internet_address::create_copy() const
00244 {
00245 return new internet_address(byte_array(ADDRESS_SIZE, ip_address),
00246 hostname, port);
00247 }
00248
00249 astring internet_address::text_form() const
00250 {
00251 astring to_print("[");
00252 if (astring(hostname).t()) {
00253 to_print += "host=";
00254 to_print += hostname;
00255 to_print += ", ";
00256 }
00260 to_print += "ip_addr=";
00261 for (int i = 0; i < ADDRESS_SIZE; i++) {
00262 to_print += a_sprintf("%d", int(ip_address[i]));
00263 if (i != ADDRESS_SIZE - 1) to_print += ".";
00264 }
00265 to_print += ", ";
00267 to_print += a_sprintf("port=%u]", port);
00268 return to_print;
00269 }
00270
00271 bool internet_address::is_nil_address(const address_array &ip_address)
00272 {
00273 for (int i = 0; i < ADDRESS_SIZE; i++) if (ip_address[i]) return false;
00274 return true;
00275 }
00276
00277 const abyte nil_address_bytes[] = { 0, 0, 0, 0 };
00278 SAFE_STATIC_CONST(byte_array, internet_address::nil_address,
00279 (ADDRESS_SIZE, nil_address_bytes))
00280
00281 bool internet_address::is_nil_address() const
00282 { return is_nil_address(ip_address); }
00283
00284 bool internet_address::same_host(const base_address &compare_in) const
00285 {
00286 CAST_UP(internet_address);
00287
00288
00289
00290
00291
00292 if ( (is_nil_address(ip_address) && is_nil_address(to_compare.ip_address))
00293 && !astring(hostname) && !astring(to_compare.hostname) )
00294 return true;
00295 if ( (is_nil_address(ip_address) && is_nil_address(to_compare.ip_address))
00296 && (astring(hostname).iequals(to_compare.hostname)) )
00297 return true;
00298 if (is_nil_address(ip_address)) return false;
00299 if (is_nil_address(to_compare.ip_address)) return false;
00300
00301
00302 for (int i = 0; i < ADDRESS_SIZE; i++)
00303 if (ip_address[i] != to_compare.ip_address[i])
00304 return false;
00305
00306
00307
00308 if (astring(hostname).t() && astring(to_compare.hostname).t()) {
00309
00310 if (astring(hostname).lower() != astring(to_compare.hostname).lower())
00311 return false;
00312 }
00313
00314 return true;
00315
00316 }
00317
00318 bool internet_address::same_port(const base_address &compare_in) const
00319 {
00320 CAST_UP(internet_address);
00321 return port == to_compare.port;
00322 }
00323
00324 bool internet_address::shareable(const base_address &) const
00325 { return true; }
00326
00327 bool internet_address::detokenize(const astring &info)
00328 {
00329 #ifdef DEBUG_ADDRESS
00330 FUNCDEF("detokenize");
00331 #endif
00332 LOADER_ENTRY;
00333
00334
00335 FIND("address", addr);
00336 #ifdef DEBUG_ADDRESS
00337 LOG(astring("info is ") + info + astring('.'));
00338 LOG(astring("addr is ") + addr);
00339 #endif
00340 byte_array ip_found;
00341 if (addr.t()) {
00342
00343
00344 for (int i = 0; i < ADDRESS_SIZE; i++) {
00345 #ifdef DEBUG_ADDRESS
00346 LOG(astring("ip curr: ") + addr);
00347 #endif
00348 int current_byte = addr.convert(int(0));
00349 ip_found += abyte(current_byte);
00350 #ifdef DEBUG_ADDRESS
00351 LOG(a_sprintf("%d: %02x ", i, current_byte));
00352 #endif
00353 int indy = addr.find('.');
00354 addr.zap(0, indy);
00355 }
00356 }
00357
00358 FIND("host", host);
00359 GRAB("port", port_t);
00360 int port = port_t.convert(0);
00361 fill(ip_found, host, port);
00362 #ifdef DEBUG_ADDRESS
00363 LOG(astring("tcp/ip address found::: ") + text_form());
00364 #endif
00365 LOADER_EXIT;
00366 return true;
00367 }
00368
00369 astring internet_address::tokenize() const
00370 {
00371 #ifdef DEBUG_ADDRESS
00372 FUNCDEF("tokenize");
00373 #endif
00374 STORER_ENTRY;
00375 #ifdef DEBUG_ADDRESS
00376 LOG(a_sprintf("host eval is %d for %s", astring(hostname).t(), hostname));
00377 #endif
00378 if (astring(hostname).t()) ADD("host", hostname);
00379 bool print_ip = false;
00380 for (int i = 0; i < ADDRESS_SIZE; i++) {
00381 if (ip_address[i]) print_ip = true;
00382 }
00383 if (print_ip) {
00384 astring ip_addr;
00385 for (int i = 0; i < ADDRESS_SIZE; i++)
00386 ip_addr += a_sprintf("%d", int(ip_address[i])) + astring(".");
00387 ip_addr.zap(ip_addr.end(), ip_addr.end());
00388 ADD("address", ip_addr);
00389 }
00390 ADD("port", a_sprintf("%d", int(port)));
00391 #ifdef DEBUG_ADDRESS
00392 LOG(astring("your toke's currently ") + fred.text_form());
00393 #endif
00394 DUMP_EXIT;
00395 }
00396
00397 bool internet_address::appropriate_for_ip(const astring &to_check)
00398 {
00399 for (int i = 0; i < to_check.length(); i++) {
00400 char curr = to_check[i];
00401 if (curr == '.') continue;
00402 if ( (curr >= '0') && (curr <= '9') ) continue;
00403
00404 return false;
00405 }
00406 return true;
00407 }
00408
00409
00410
00411
00412 bool internet_address::is_valid_internet_address(const astring &to_check,
00413 byte_array &ip_form, bool &all_zeros)
00414 {
00415 astring tmpstr = to_check;
00416 all_zeros = true;
00417 ip_form.reset();
00418
00419
00420 if (!appropriate_for_ip(to_check)) return false;
00421
00422
00423 if ( (to_check[0] == '.') || (to_check[to_check.end()] == '.') )
00424 return false;
00425
00426
00427 if (to_check.contains("..")) return false;
00428
00429
00430 char *p = strtok(tmpstr.s(), ".");
00431
00432 int index = 0;
00433 while (p && (index < ADDRESS_SIZE)) {
00434 int nTemp = astring(p).convert(-1);
00435
00436
00437 if ( (nTemp < 0) || (nTemp > 255) ) return false;
00438
00439
00440 ip_form += (abyte)nTemp;
00441
00442
00443 p = strtok(NIL, ".");
00444 }
00445
00446
00447 if (p) return false;
00448
00449 for (int i = 0; i < ip_form.length(); i++)
00450 if (ip_form[i]) { all_zeros = false; break; }
00451
00452 return ip_form.length() == ADDRESS_SIZE;
00453 }
00454
00455 bool internet_address::valid_address(const astring &to_check)
00456 {
00457 byte_array addr;
00458 bool all_zeros;
00459 return is_valid_internet_address(to_check, addr, all_zeros);
00460 }
00461
00462 astring internet_address::ip_address_text_form(const byte_array &ip_address)
00463 {
00464 return a_sprintf("%d.%d.%d.%d", int(ip_address[0]),
00465 int(ip_address[1]), int(ip_address[2]), int(ip_address[3]));
00466 }
00467
00468 }
00469
00470