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
00375 void WvIPAddr::string_init(const char string[])
00376 {
00377 const char *iptr, *nptr;
00378 unsigned char *cptr = binaddr;
00379
00380 memset(binaddr, 0, 4);
00381 nptr = string;
00382 for (int count=0; count < 4 && nptr; count++)
00383 {
00384 iptr = nptr;
00385 nptr = strchr(iptr, '.');
00386 if (nptr) nptr++;
00387 *cptr++ = strtol(iptr, NULL, 10);
00388 if (!nptr) break;
00389 }
00390 }
00391
00392 WvIPAddr::~WvIPAddr()
00393 {
00394
00395 }
00396
00397 bool WvIPAddr::comparator(const WvAddr *a2, bool first_pass) const
00398 {
00399 if (a2->type() == WVIPADDR)
00400 return !memcmp(binaddr, ((WvIPAddr *)a2)->binaddr, sizeof(binaddr));
00401 else if (first_pass)
00402 return a2->comparator(this, false);
00403 else
00404 {
00405 const unsigned char *raw1, *raw2;
00406 size_t len;
00407
00408 len = rawdata_len();
00409 if (len != a2->rawdata_len())
00410 return false;
00411
00412 raw1 = rawdata();
00413 raw2 = a2->rawdata();
00414
00415 if (!raw1 && !raw2) return true;
00416 if (!raw1 || !raw2) return false;
00417
00418 return !memcmp(raw1, raw2, len);
00419 }
00420 }
00421
00422
00423
00424 WvString WvIPAddr::printable() const
00425 {
00426 return WvString("%s.%s.%s.%s",
00427 binaddr[0], binaddr[1], binaddr[2], binaddr[3]);
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 WvIPAddr &a2) const
00455 {
00456 unsigned char obin[4];
00457
00458 for (int count=0; count<4; count++)
00459 obin[count] = binaddr[count] ^ a2.binaddr[count];
00460 return WvIPAddr(obin);
00461 }
00462
00463
00464
00465 WvIPAddr WvIPAddr::operator~ () const
00466 {
00467 unsigned char obin[4];
00468
00469 for (int count=0; count<4; count++)
00470 obin[count] = ~binaddr[count];
00471 return WvIPAddr(obin);
00472 }
00473
00474
00475
00476
00477
00478 WvIPAddr WvIPAddr::operator+ (int n) const
00479 {
00480 uint32_t newad = htonl(ntohl(addr()) + n);
00481 return WvIPAddr((unsigned char *)&newad);
00482 }
00483
00484
00485 WvIPAddr WvIPAddr::operator- (int n) const
00486 {
00487 uint32_t newad = htonl(ntohl(addr()) - n);
00488 return WvIPAddr((unsigned char *)&newad);
00489 }
00490
00491
00492 WvEncap WvIPAddr::encap() const
00493 {
00494 return WvEncap(WvEncap::IPv4);
00495 }
00496
00497
00498 const unsigned char *WvIPAddr::rawdata() const
00499 {
00500 return binaddr;
00501 }
00502
00503
00504 size_t WvIPAddr::rawdata_len() const
00505 {
00506 return 4;
00507 }
00508
00509
00510
00511
00512
00513 sockaddr_bin *WvIPAddr::sockaddr() const
00514 {
00515 sockaddr_in *sin = new sockaddr_in;
00516
00517 memset(sin, 0, sizeof(*sin));
00518 sin->sin_family = AF_INET;
00519 sin->sin_addr.s_addr = addr();
00520 sin->sin_port = 0;
00521 return (sockaddr_bin *)sin;
00522 }
00523
00524
00525 size_t WvIPAddr::sockaddr_len() const
00526 {
00527 return sizeof(sockaddr_in);
00528 }
00529
00530
00531 WvIPNet::WvIPNet() { }
00532
00533
00534 WvIPNet::WvIPNet(const WvIPNet &_net)
00535 : WvIPAddr(_net), mask(_net.netmask()) { }
00536
00537
00538
00539 void WvIPNet::string_init(const char string[])
00540 {
00541 char *maskptr;
00542 int bits;
00543 uint32_t imask;
00544
00545 maskptr = (char*)strchr(string, '/');
00546 if (!maskptr)
00547 {
00548 mask = WvIPAddr("255.255.255.255");
00549 return;
00550 }
00551
00552 maskptr++;
00553
00554 if (strchr(maskptr, '.'))
00555 mask = WvIPAddr(maskptr);
00556 else
00557 {
00558 bits = atoi(maskptr);
00559 if (bits > 0)
00560 imask = htonl(~(((uint32_t)1 << (32-bits)) - 1));
00561 else
00562 imask = 0;
00563 mask = WvIPAddr((unsigned char *)&imask);
00564 }
00565 }
00566
00567
00568 WvIPNet::WvIPNet(const WvIPAddr &base, const WvIPAddr &_mask)
00569 : WvIPAddr(base), mask(_mask) { }
00570
00571
00572 WvIPNet::WvIPNet(const WvIPAddr &base, int bits)
00573 : WvIPAddr(base)
00574 {
00575 uint32_t imask;
00576 if (bits > 0)
00577 imask = htonl(~(((uint32_t)1 << (32-bits)) - 1));
00578 else
00579 imask = 0;
00580 mask = WvIPAddr((unsigned char *)&imask);
00581 }
00582
00583 WvIPNet::~WvIPNet()
00584 {
00585
00586 }
00587
00588
00589 WvString WvIPNet::printable() const
00590 {
00591 if (bits() < 32)
00592 return WvString("%s/%s", network(), bits());
00593 else
00594 return WvIPAddr::printable();
00595 }
00596
00597
00598 unsigned WvIPNet::WvHash() const
00599 {
00600 return WvIPAddr::WvHash() + mask.WvHash();
00601 }
00602
00603
00604 bool WvIPNet::comparator(const WvAddr *a2, bool first_pass) const
00605 {
00606 if (a2->type() == WVIPNET)
00607 return WvIPAddr::comparator(a2, false) && mask == ((WvIPNet *)a2)->mask;
00608 else if (first_pass)
00609 return a2->comparator(this, false);
00610 else
00611 return WvIPAddr::comparator(a2, false);
00612
00613 }
00614
00615
00616 void WvIPNet::include(const WvIPNet &addr)
00617 {
00618 mask = mask & addr.mask & ~(*this ^ addr);
00619 }
00620
00621
00622 bool WvIPNet::includes(const WvIPNet &addr) const
00623 {
00624 return (addr.base() & netmask()) == network() &&
00625 (addr.netmask() & netmask()) == netmask();
00626 }
00627
00628
00629 int WvIPNet::bits() const
00630 {
00631 int bits = 0;
00632 uint32_t val = ntohl(mask.addr());
00633
00634 do
00635 {
00636 bits += val >> 31;
00637 } while ((val <<= 1) & (1 << 31));
00638
00639 return bits;
00640 }
00641
00642
00643 void WvIPNet::normalize()
00644 {
00645 if (bits() > 0)
00646 {
00647 uint32_t val = htonl(~(((uint32_t)1 << (32-bits())) - 1));
00648 mask = WvIPAddr((unsigned char *)&val);
00649 }
00650 else
00651 mask = WvIPAddr();
00652 }
00653
00654
00655 WvIPPortAddr::WvIPPortAddr()
00656 {
00657 port = 0;
00658 }
00659
00660
00661 WvIPPortAddr::WvIPPortAddr(const WvIPAddr &_ipaddr, uint16_t _port)
00662 : WvIPAddr(_ipaddr)
00663 {
00664 port = _port;
00665 }
00666
00667
00668 static bool all_digits(const char *s)
00669 {
00670 for (; *s; s++)
00671 if (!isdigit((unsigned char)*s))
00672 return false;
00673 return true;
00674 }
00675
00676
00677
00678 void WvIPPortAddr::string_init(const char string[])
00679 {
00680
00681
00682 if (all_digits(string))
00683 {
00684 *this = WvIPAddr();
00685 port = atoi(string);
00686 return;
00687 }
00688
00689 const char *cptr = strchr(string, ':');
00690 if (!cptr)
00691 cptr = strchr(string, ' ');
00692 if (!cptr)
00693 cptr = strchr(string, '\t');
00694
00695
00696
00697 if (cptr && strcmp(cptr+1, "0"))
00698 {
00699 port = atoi(cptr+1);
00700 if (!port)
00701 {
00702 struct servent *serv = getservbyname(cptr+1, NULL);
00703 if (serv)
00704 port = ntohs(serv->s_port);
00705 }
00706 }
00707 else
00708 port = 0;
00709 }
00710
00711
00712 WvIPPortAddr::WvIPPortAddr(uint16_t _port)
00713 : WvIPAddr("0.0.0.0")
00714 {
00715 port = _port;
00716 }
00717
00718
00719 WvIPPortAddr::WvIPPortAddr(const char string[], uint16_t _port)
00720 : WvIPAddr(string)
00721 {
00722 port = _port;
00723 }
00724
00725
00726 WvIPPortAddr::~WvIPPortAddr()
00727 {
00728
00729 }
00730
00731
00732
00733 WvString WvIPPortAddr::printable() const
00734 {
00735 return WvString("%s:%s", WvIPAddr::printable(), WvString(port));
00736 }
00737
00738
00739
00740
00741
00742 sockaddr_bin *WvIPPortAddr::sockaddr() const
00743 {
00744 sockaddr_in *sin = (sockaddr_in *)WvIPAddr::sockaddr();
00745 sin->sin_port = htons(port);
00746 return (sockaddr_bin *)sin;
00747 }
00748
00749
00750 unsigned WvIPPortAddr::WvHash() const
00751 {
00752 return WvIPAddr::WvHash() + port;
00753 }
00754
00755 bool WvIPPortAddr::comparator(const WvAddr *a2, bool first_pass) const
00756 {
00757 if (a2->type() == WVIPPORTADDR)
00758 return WvIPAddr::comparator(a2, false)
00759 && port == ((WvIPPortAddr *)a2)->port;
00760 else if (first_pass)
00761 return a2->comparator(this, false);
00762 else
00763 return WvIPAddr::comparator(a2, false);
00764
00765 }
00766
00767 #ifndef _WIN32
00768 WvUnixAddr::WvUnixAddr(const char *_sockname)
00769 : sockname(_sockname)
00770 {
00771 if (!sockname)
00772 sockname = "/";
00773 }
00774
00775
00776 WvUnixAddr::WvUnixAddr(WvStringParm _sockname)
00777 : sockname(_sockname)
00778 {
00779 if (!sockname)
00780 sockname = "/";
00781 }
00782
00783
00784 WvUnixAddr::WvUnixAddr(const WvUnixAddr &_addr)
00785 : sockname(_addr.sockname)
00786 {
00787
00788 }
00789
00790
00791 WvUnixAddr::~WvUnixAddr()
00792 {
00793
00794 }
00795
00796
00797 WvString WvUnixAddr::printable() const
00798 {
00799 return sockname;
00800 }
00801
00802
00803 WvEncap WvUnixAddr::encap() const
00804 {
00805 return WvEncap::Unix;
00806 }
00807
00808
00809
00810 sockaddr_bin *WvUnixAddr::sockaddr() const
00811 {
00812 sockaddr_un *addr = new sockaddr_un;
00813
00814 memset(addr, 0, sizeof(*addr));
00815 addr->sun_family = AF_UNIX;
00816 size_t max = strlen(sockname);
00817 if (max > sizeof(addr->sun_path) - 2)
00818 max = sizeof(addr->sun_path) - 2;
00819 strncpy(addr->sun_path, sockname, max);
00820 if (addr->sun_path[0] == '@')
00821 addr->sun_path[0] = 0;
00822 return (sockaddr_bin *)addr;
00823 }
00824
00825
00826 size_t WvUnixAddr::sockaddr_len() const
00827 {
00828 sockaddr_un *fake;
00829 size_t max = sizeof(fake->sun_path);
00830 size_t val = strlen(sockname);
00831 if (val > max)
00832 val = max;
00833 return sizeof(fake->sun_family) + val;
00834 }
00835
00836
00837 const unsigned char *WvUnixAddr::rawdata() const
00838 {
00839 return (const unsigned char *)(const char *)sockname;
00840 }
00841
00842
00843 size_t WvUnixAddr::rawdata_len() const
00844 {
00845 return strlen(sockname);
00846 }
00847 #endif // _WIN32