00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef _WIN32
00010 #include <netdb.h>
00011 #include <sys/socket.h>
00012 #include <sys/un.h>
00013 #include <net/if_arp.h>
00014 #endif
00015
00016 #include "wvaddr.h"
00017 #include <assert.h>
00018
00019
00020 typedef struct sockaddr sockaddr_bin;
00021
00022
00023 int WvEncap::extypes[] = {
00024 #ifdef _WIN32
00025 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00026 #else
00027
00028 0,
00029 ARPHRD_LOOPBACK,
00030 0,
00031 ARPHRD_ETHER,
00032 ARPHRD_ARCNET,
00033 ARPHRD_SLIP,
00034 ARPHRD_CSLIP,
00035 ARPHRD_PPP,
00036
00037
00038 AF_INET,
00039 AF_UNIX
00040 #endif
00041 };
00042
00043
00044
00045 char WvEncap::strings[][20] = {
00046
00047 "Unknown",
00048 "Loopback",
00049 "Ethertap",
00050 "Ethernet",
00051 "ARCnet",
00052 "SLIP",
00053 "CSLIP",
00054 "PPP",
00055
00056
00057 "IP",
00058 "Unix",
00059 };
00060
00061
00062
00063
00064
00065 WvEncap::WvEncap(int extype)
00066 {
00067 for (int count=0; count < NUM_ENCAP_TYPES; count++)
00068 {
00069 if (extype == extypes[count])
00070 {
00071 cap = (CapType)count;
00072 return;
00073 }
00074 }
00075 cap = Unknown;
00076 }
00077
00078
00079
00080 unsigned WvHash(const WvAddr &addr)
00081 {
00082 return addr.WvHash();
00083 }
00084
00085
00086
00087
00088
00089 WvAddr *WvAddr::gen(struct sockaddr *addr)
00090 {
00091 WvEncap encap(addr->sa_family);
00092
00093 switch (encap.cap)
00094 {
00095 case WvEncap::Loopback:
00096 return new WvStringAddr("Loopback", WvEncap::Loopback);
00097
00098 case WvEncap::IPv4:
00099 return new WvIPPortAddr((sockaddr_in *)addr);
00100 #ifndef _WIN32
00101 case WvEncap::ARCnet:
00102 return new WvARCnetAddr(addr);
00103
00104 case WvEncap::Ethertap:
00105 case WvEncap::Ethernet:
00106 return new WvEtherAddr(addr);
00107 #endif
00108 default:
00109 return new WvStringAddr("Unknown", WvEncap::Unknown);
00110 }
00111 }
00112
00113
00114 bool WvAddr::isbroadcast() const
00115 {
00116 return false;
00117 }
00118
00119
00120 const unsigned char *WvAddr::rawdata() const
00121 {
00122 return NULL;
00123 }
00124
00125
00126 size_t WvAddr::rawdata_len() const
00127 {
00128 return 0;
00129 }
00130
00131
00132 unsigned WvAddr::WvHash() const
00133 {
00134 unsigned hash = 0;
00135 const unsigned char *cptr, *raw = rawdata();
00136 int len = rawdata_len(), width;
00137
00138 if (!raw || !len) return 0;
00139 width = (sizeof(hash)*8 / len) + 1;
00140
00141 for (cptr = raw; len; len--)
00142 hash = (hash << width) ^ *(cptr++);
00143 return hash;
00144 }
00145
00146
00147 bool WvAddr::comparator(const WvAddr *a2, bool first_pass) const
00148 {
00149 if (type() != a2->type()) return false;
00150
00151 const unsigned char *raw1, *raw2;
00152 size_t len;
00153
00154 len = rawdata_len();
00155 if (len != a2->rawdata_len())
00156 return false;
00157
00158 raw1 = rawdata();
00159 raw2 = a2->rawdata();
00160
00161 if (!raw1 && !raw2) return true;
00162 if (!raw1 || !raw2) return false;
00163
00164 return !memcmp(raw1, raw2, len);
00165 }
00166
00167
00168 WvStringAddr::WvStringAddr(WvStringParm s, const WvEncap &_cap)
00169 : addr(s), cap(_cap)
00170 {
00171 }
00172
00173
00174 WvStringAddr::WvStringAddr(const struct sockaddr *_addr)
00175 : addr((char *)_addr->sa_data), cap(_addr->sa_family)
00176 {
00177 }
00178
00179
00180 WvStringAddr::~WvStringAddr()
00181 {
00182
00183 }
00184
00185
00186 WvEncap WvStringAddr::encap() const
00187 {
00188 return cap;
00189 }
00190
00191
00192 const unsigned char *WvStringAddr::rawdata() const
00193 {
00194 return (const unsigned char *)(const char *)addr;
00195 }
00196
00197
00198 size_t WvStringAddr::rawdata_len() const
00199 {
00200 return strlen(addr);
00201 }
00202
00203
00204 sockaddr_bin *WvStringAddr::sockaddr() const
00205 {
00206 sockaddr_bin *sa = new sockaddr_bin;
00207 memset(sa, 0, sizeof(*sa));
00208 strncpy(sa->sa_data, addr, sizeof(sa->sa_data));
00209 return sa;
00210 }
00211
00212
00213 size_t WvStringAddr::sockaddr_len() const
00214 {
00215 return sizeof(sockaddr_bin);
00216 }
00217
00218
00219 WvString WvStringAddr::printable() const
00220 {
00221 return addr;
00222 }
00223
00224
00225 #ifndef _WIN32
00226
00227
00228
00229 void WvEtherAddr::string_init(char const string[])
00230 {
00231 char *endptr = NULL;
00232 unsigned char *cptr = binaddr;
00233
00234 memset(binaddr, 0, ETH_ALEN);
00235 for (int count=0; count < ETH_ALEN; count++)
00236 {
00237 *cptr++ = strtoul(endptr ? endptr : string, &endptr, 16);
00238 if (!endptr || endptr==string) break;
00239 endptr++;
00240 }
00241 }
00242
00243
00244 WvEtherAddr::~WvEtherAddr()
00245 {
00246
00247 }
00248
00249
00250
00251 WvString WvEtherAddr::printable() const
00252 {
00253 char s[ETH_ALEN*3], *cptr = s;
00254
00255 for (int count = 0; count < ETH_ALEN; count++)
00256 {
00257 if (cptr > s)
00258 *cptr++ = ':';
00259 sprintf(cptr, "%02X", binaddr[count]);
00260 cptr += 2;
00261 }
00262 *cptr = 0;
00263
00264 return WvString("%s", s);
00265 }
00266
00267
00268 WvEncap WvEtherAddr::encap() const
00269 {
00270 return WvEncap(WvEncap::Ethernet);
00271 }
00272
00273
00274
00275 bool WvEtherAddr::isbroadcast() const
00276 {
00277 for (int count = 0; count < ETH_ALEN; count++)
00278 if (binaddr[count] != 0xFF)
00279 return false;
00280 return true;
00281 }
00282
00283
00284 const unsigned char *WvEtherAddr::rawdata() const
00285 {
00286 return binaddr;
00287 }
00288
00289
00290 size_t WvEtherAddr::rawdata_len() const
00291 {
00292 return ETH_ALEN;
00293 }
00294
00295
00296 sockaddr_bin *WvEtherAddr::sockaddr() const
00297 {
00298 sockaddr_bin *sa = new sockaddr_bin;
00299 memset(sa, 0, sizeof(*sa));
00300 sa->sa_family = ARPHRD_ETHER;
00301 memcpy(sa->sa_data, binaddr, ETH_ALEN);
00302 return sa;
00303 }
00304
00305
00306 size_t WvEtherAddr::sockaddr_len() const
00307 {
00308 return sizeof(sockaddr_bin);
00309 }
00310
00311
00312 WvARCnetAddr::~WvARCnetAddr()
00313 {
00314
00315 }
00316
00317
00318 WvString WvARCnetAddr::printable() const
00319 {
00320 WvString s(" ");
00321 sprintf(s.edit(), "%02X", binaddr);
00322 return s;
00323 }
00324
00325
00326 WvEncap WvARCnetAddr::encap() const
00327 {
00328 return WvEncap(WvEncap::ARCnet);
00329 }
00330
00331
00332 const unsigned char *WvARCnetAddr::rawdata() const
00333 {
00334 return &binaddr;
00335 }
00336
00337
00338 size_t WvARCnetAddr::rawdata_len() const
00339 {
00340 return 1;
00341 }
00342
00343
00344 sockaddr_bin *WvARCnetAddr::sockaddr() const
00345 {
00346 sockaddr_bin *sa = new sockaddr_bin;
00347 memset(sa, 0, sizeof(*sa));
00348 sa->sa_family = ARPHRD_ARCNET;
00349 sa->sa_data[0] = binaddr;
00350 return sa;
00351 }
00352
00353
00354 size_t WvARCnetAddr::sockaddr_len() const
00355 {
00356 return sizeof(sockaddr_bin);
00357 }
00358
00359 #endif //_WIN32
00360
00361
00362
00363
00364 void WvIPAddr::string_init(const char string[])
00365 {
00366 const char *iptr, *nptr;
00367 unsigned char *cptr = binaddr;
00368
00369 memset(binaddr, 0, 4);
00370 nptr = string;
00371 for (int count=0; count < 4 && nptr; count++)
00372 {
00373 iptr = nptr;
00374 nptr = strchr(iptr, '.');
00375 if (nptr) nptr++;
00376 *cptr++ = strtol(iptr, NULL, 10);
00377 if (!nptr) break;
00378 }
00379 }
00380
00381 WvIPAddr::~WvIPAddr()
00382 {
00383
00384 }
00385
00386 bool WvIPAddr::comparator(const WvAddr *a2, bool first_pass) const
00387 {
00388 if (a2->type() == WVIPADDR)
00389 return !memcmp(binaddr, ((WvIPAddr *)a2)->binaddr, sizeof(binaddr));
00390 else if (first_pass)
00391 return a2->comparator(this, false);
00392 else
00393 {
00394 const unsigned char *raw1, *raw2;
00395 size_t len;
00396
00397 len = rawdata_len();
00398 if (len != a2->rawdata_len())
00399 return false;
00400
00401 raw1 = rawdata();
00402 raw2 = a2->rawdata();
00403
00404 if (!raw1 && !raw2) return true;
00405 if (!raw1 || !raw2) return false;
00406
00407 return !memcmp(raw1, raw2, len);
00408 }
00409 }
00410
00411
00412
00413 WvString WvIPAddr::printable() const
00414 {
00415 return WvString("%s.%s.%s.%s",
00416 binaddr[0], binaddr[1], binaddr[2], binaddr[3]);
00417 }
00418
00419
00420
00421 WvIPAddr WvIPAddr::operator& (const WvIPAddr &a2) const
00422 {
00423 unsigned char obin[4];
00424
00425 for (int count=0; count<4; count++)
00426 obin[count] = binaddr[count] & a2.binaddr[count];
00427 return WvIPAddr(obin);
00428 }
00429
00430
00431
00432 WvIPAddr WvIPAddr::operator| (const WvIPAddr &a2) const
00433 {
00434 unsigned char obin[4];
00435
00436 for (int count=0; count<4; count++)
00437 obin[count] = binaddr[count] | a2.binaddr[count];
00438 return WvIPAddr(obin);
00439 }
00440
00441
00442
00443 WvIPAddr WvIPAddr::operator^ (const WvIPAddr &a2) const
00444 {
00445 unsigned char obin[4];
00446
00447 for (int count=0; count<4; count++)
00448 obin[count] = binaddr[count] ^ a2.binaddr[count];
00449 return WvIPAddr(obin);
00450 }
00451
00452
00453
00454 WvIPAddr WvIPAddr::operator~ () const
00455 {
00456 unsigned char obin[4];
00457
00458 for (int count=0; count<4; count++)
00459 obin[count] = ~binaddr[count];
00460 return WvIPAddr(obin);
00461 }
00462
00463
00464
00465
00466
00467 WvIPAddr WvIPAddr::operator+ (int n) const
00468 {
00469 __u32 newad = htonl(ntohl(addr()) + n);
00470 return WvIPAddr((unsigned char *)&newad);
00471 }
00472
00473
00474 WvIPAddr WvIPAddr::operator- (int n) const
00475 {
00476 __u32 newad = htonl(ntohl(addr()) - n);
00477 return WvIPAddr((unsigned char *)&newad);
00478 }
00479
00480
00481 WvEncap WvIPAddr::encap() const
00482 {
00483 return WvEncap(WvEncap::IPv4);
00484 }
00485
00486
00487 const unsigned char *WvIPAddr::rawdata() const
00488 {
00489 return binaddr;
00490 }
00491
00492
00493 size_t WvIPAddr::rawdata_len() const
00494 {
00495 return 4;
00496 }
00497
00498
00499
00500
00501
00502 sockaddr_bin *WvIPAddr::sockaddr() const
00503 {
00504 sockaddr_in *sin = new sockaddr_in;
00505
00506 memset(sin, 0, sizeof(*sin));
00507 sin->sin_family = AF_INET;
00508 sin->sin_addr.s_addr = addr();
00509 sin->sin_port = 0;
00510 return (sockaddr_bin *)sin;
00511 }
00512
00513
00514 size_t WvIPAddr::sockaddr_len() const
00515 {
00516 return sizeof(sockaddr_in);
00517 }
00518
00519
00520 WvIPNet::WvIPNet() { }
00521
00522
00523 WvIPNet::WvIPNet(const WvIPNet &_net)
00524 : WvIPAddr(_net), mask(_net.netmask()) { }
00525
00526
00527
00528 void WvIPNet::string_init(const char string[])
00529 {
00530 char *maskptr;
00531 int bits;
00532 __u32 imask;
00533
00534 maskptr = strchr(string, '/');
00535 if (!maskptr)
00536 {
00537 mask = WvIPAddr("255.255.255.255");
00538 return;
00539 }
00540
00541 maskptr++;
00542
00543 if (strchr(maskptr, '.'))
00544 mask = WvIPAddr(maskptr);
00545 else
00546 {
00547 bits = atoi(maskptr);
00548 if (bits > 0)
00549 imask = htonl(~(((__u32)1 << (32-bits)) - 1));
00550 else
00551 imask = 0;
00552 mask = WvIPAddr((unsigned char *)&imask);
00553 }
00554 }
00555
00556
00557 WvIPNet::WvIPNet(const WvIPAddr &base, const WvIPAddr &_mask)
00558 : WvIPAddr(base), mask(_mask) { }
00559
00560
00561 WvIPNet::WvIPNet(const WvIPAddr &base, int bits)
00562 : WvIPAddr(base)
00563 {
00564 __u32 imask;
00565 if (bits > 0)
00566 imask = htonl(~(((__u32)1 << (32-bits)) - 1));
00567 else
00568 imask = 0;
00569 mask = WvIPAddr((unsigned char *)&imask);
00570 }
00571
00572 WvIPNet::~WvIPNet()
00573 {
00574
00575 }
00576
00577
00578 WvString WvIPNet::printable() const
00579 {
00580 if (bits() < 32)
00581 return WvString("%s/%s", network(), bits());
00582 else
00583 return WvIPAddr::printable();
00584 }
00585
00586
00587 unsigned WvIPNet::WvHash() const
00588 {
00589 return WvIPAddr::WvHash() + mask.WvHash();
00590 }
00591
00592
00593 bool WvIPNet::comparator(const WvAddr *a2, bool first_pass) const
00594 {
00595 if (a2->type() == WVIPNET)
00596 return WvIPAddr::comparator(a2, false) && mask == ((WvIPNet *)a2)->mask;
00597 else if (first_pass)
00598 return a2->comparator(this, false);
00599 else
00600 return WvIPAddr::comparator(a2, false);
00601
00602 }
00603
00604
00605 void WvIPNet::include(const WvIPNet &addr)
00606 {
00607 mask = mask & addr.mask & ~(*this ^ addr);
00608 }
00609
00610
00611 bool WvIPNet::includes(const WvIPNet &addr) const
00612 {
00613 return (addr.base() & netmask()) == network() &&
00614 (addr.netmask() & netmask()) == netmask();
00615 }
00616
00617
00618 int WvIPNet::bits() const
00619 {
00620 int bits = 0;
00621 __u32 val = ntohl(mask.addr());
00622
00623 do
00624 {
00625 bits += val >> 31;
00626 } while ((val <<= 1) & (1 << 31));
00627
00628 return bits;
00629 }
00630
00631
00632 void WvIPNet::normalize()
00633 {
00634 if (bits() > 0)
00635 {
00636 __u32 val = htonl(~(((__u32)1 << (32-bits())) - 1));
00637 mask = WvIPAddr((unsigned char *)&val);
00638 }
00639 else
00640 mask = WvIPAddr();
00641 }
00642
00643
00644 WvIPPortAddr::WvIPPortAddr()
00645 {
00646 port = 0;
00647 }
00648
00649
00650 WvIPPortAddr::WvIPPortAddr(const WvIPAddr &_ipaddr, __u16 _port)
00651 : WvIPAddr(_ipaddr)
00652 {
00653 port = _port;
00654 }
00655
00656
00657
00658 void WvIPPortAddr::string_init(const char string[])
00659 {
00660 struct servent* serv;
00661
00662 const char *cptr = strchr(string, ':');
00663 if (!cptr)
00664 cptr = strchr(string, ' ');
00665 if (!cptr)
00666 cptr = strchr(string, '\t');
00667
00668
00669
00670 if (cptr && strcmp(cptr+1, "0"))
00671 {
00672 port = atoi(cptr+1);
00673 if (!port)
00674 {
00675 serv = getservbyname(cptr+1, NULL);
00676 if (serv)
00677 port = ntohs(serv->s_port);
00678 }
00679 }
00680 else
00681 port = 0;
00682 }
00683
00684
00685 WvIPPortAddr::WvIPPortAddr(__u16 _port)
00686 : WvIPAddr("0.0.0.0")
00687 {
00688 port = _port;
00689 }
00690
00691
00692 WvIPPortAddr::WvIPPortAddr(const char string[], __u16 _port)
00693 : WvIPAddr(string)
00694 {
00695 port = _port;
00696 }
00697
00698
00699 WvIPPortAddr::~WvIPPortAddr()
00700 {
00701
00702 }
00703
00704
00705
00706 WvString WvIPPortAddr::printable() const
00707 {
00708 return WvString("%s:%s", WvIPAddr::printable(), WvString(port));
00709 }
00710
00711
00712
00713
00714
00715 sockaddr_bin *WvIPPortAddr::sockaddr() const
00716 {
00717 sockaddr_in *sin = (sockaddr_in *)WvIPAddr::sockaddr();
00718 sin->sin_port = htons(port);
00719 return (sockaddr_bin *)sin;
00720 }
00721
00722
00723 unsigned WvIPPortAddr::WvHash() const
00724 {
00725 return WvIPAddr::WvHash() + port;
00726 }
00727
00728 bool WvIPPortAddr::comparator(const WvAddr *a2, bool first_pass) const
00729 {
00730 if (a2->type() == WVIPPORTADDR)
00731 return WvIPAddr::comparator(a2, false)
00732 && port == ((WvIPPortAddr *)a2)->port;
00733 else if (first_pass)
00734 return a2->comparator(this, false);
00735 else
00736 return WvIPAddr::comparator(a2, false);
00737
00738 }
00739
00740 #ifndef _WIN32
00741 WvUnixAddr::WvUnixAddr(const char *_sockname)
00742 : sockname(_sockname)
00743 {
00744 assert(!!sockname);
00745 }
00746
00747
00748 WvUnixAddr::WvUnixAddr(WvStringParm _sockname)
00749 : sockname(_sockname)
00750 {
00751 assert(!!sockname);
00752 }
00753
00754
00755 WvUnixAddr::WvUnixAddr(const WvUnixAddr &_addr)
00756 : sockname(_addr.sockname)
00757 {
00758
00759 }
00760
00761
00762 WvUnixAddr::~WvUnixAddr()
00763 {
00764
00765 }
00766
00767
00768 WvString WvUnixAddr::printable() const
00769 {
00770 return sockname;
00771 }
00772
00773
00774 WvEncap WvUnixAddr::encap() const
00775 {
00776 return WvEncap::Unix;
00777 }
00778
00779
00780
00781 sockaddr_bin *WvUnixAddr::sockaddr() const
00782 {
00783 sockaddr_un *sun = new sockaddr_un;
00784
00785 memset(sun, 0, sizeof(*sun));
00786 sun->sun_family = AF_UNIX;
00787 strncpy(sun->sun_path, sockname, sizeof(sun->sun_path) - 2);
00788 return (sockaddr_bin *)sun;
00789 }
00790
00791
00792 size_t WvUnixAddr::sockaddr_len() const
00793 {
00794 return sizeof(sockaddr_un);
00795 }
00796
00797
00798 const unsigned char *WvUnixAddr::rawdata() const
00799 {
00800 return (const unsigned char *)(const char *)sockname;
00801 }
00802
00803
00804 size_t WvUnixAddr::rawdata_len() const
00805 {
00806 return strlen(sockname);
00807 }
00808 #endif // _WIN32