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