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