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