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