• Main Page
  • Modules
  • Classes
  • Files
  • File List
  • File Members

wvaddr.cc

00001 /*
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  * 
00005  * Device-independent and device-specific hardware/protocol address
00006  * classes that can store themselves efficiently as well as create a
00007  * printable string version of themselves.
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 // From ipsec_tunnel
00024 #define ARPHRD_IPSEC 31
00025 #endif
00026 
00027 // workaround for functions called sockaddr() -- oops.
00028 typedef struct sockaddr sockaddr_bin;
00029 
00030 /* A list of Linux ARPHRD_* types, one for each element of CapType. */
00031 int WvEncap::extypes[] = {
00032 #ifdef _WIN32
00033     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00034 #else
00035     // hardware encapsulation
00036     0, // Unknown
00037     ARPHRD_LOOPBACK,
00038     0, // Ethertap
00039     ARPHRD_ETHER,
00040     ARPHRD_ARCNET,
00041     ARPHRD_SLIP,
00042     ARPHRD_CSLIP,
00043     ARPHRD_PPP,
00044     ARPHRD_IPSEC,
00045     
00046     // protocol encapsulation
00047     AF_INET, // IPv4
00048     AF_UNIX  // Unix domain socket
00049 #endif
00050 };
00051 
00052 
00053 /* Printable strings corresponding to each element of CapType */
00054 const char WvEncap::strings[][20] = {
00055     // hardware encapsulation
00056     "Unknown",
00057     "Loopback",
00058     "Ethertap",
00059     "Ethernet",
00060     "ARCnet",
00061     "SLIP",
00062     "CSLIP",
00063     "PPP",
00064     "IPsec",
00065     
00066     // protocol encapsulation
00067     "IP", // IPv4
00068     "Unix", // Unix domain socket
00069 };
00070 
00071 
00072 /* Figure out the CapType corresponding to a Linux ARPHRD_* type or
00073  * sockaddr sa_family type.
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 /* Find the hash value of a WvAddr, for use with WvHashTable */
00090 unsigned WvHash(const WvAddr &addr)
00091 {
00092     return addr.WvHash();
00093 }
00094 
00095 
00096 /* Create an object of the appropriate WvAddr-derived class based on the
00097  * address and type stored in 'addr'.
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; // default is no support for broadcasts
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     // nothing to do
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 /* create a WvEtherAddr from a printable string in the format:
00240  *      AA:BB:CC:DD:EE:FF  (six hex numbers, separated by colons)
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     // nothing to do
00260 }
00261 
00262 
00263 /* Generate a printable version of an ethernet address. */
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); // create a dynamic WvString
00278 }
00279 
00280 
00281 WvEncap WvEtherAddr::encap() const
00282 {
00283     return WvEncap(WvEncap::Ethernet);
00284 }
00285 
00286 
00287 // FF:FF:FF:FF:FF:FF is the ethernet broadcast address.
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     // nothing to do
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 /* create an IP address from a dotted-quad string.  We don't support
00375  * gethostname()-style lookups here, because they happen only synchronously.
00376  * Streams that need hostname lookups will have to do it themselves.
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     // nothing to do
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 /* Generate a printable version of an IP address. */
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 /* AND two IP addresses together (handle netmasks) */
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 /* OR two IP addresses together (for broadcasts, etc) */
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 /* XOR two IP addresses together (for binary operations) */
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 /* invert all the bits of an IP address (for useful binary operations) */
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 /* add an integer value to an IP address:
00479  *   eg. 192.168.42.255 + 1 == 192.168.43.0
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 /* Generate a struct sockaddr (suitable for sendto()) from this IP
00514  * address.  Don't forget to delete it after you're done!
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 // If the netmask is not specified, it will default to all 1's.
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)); // see below
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) // <<32 is a bad idea!
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     // nothing to do
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(); // empty netmask
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 // If no port is specified (after a ':' or a space or a tab) it defaults to 0.
00681 void WvIPPortAddr::string_init(const char string[]) 
00682 {
00683     // special case for an all-numeric string: it must be just a port,
00684     // with default address 0.0.0.0.
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     // avoid calling getservbyname() if we can avoid it, since it's really
00699     // slow and people like to create WvIPPortAddr objects really often.
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     // nothing to do
00732 }
00733 
00734 
00735 /* Generate a printable version of an IP+Port Address. */
00736 WvString WvIPPortAddr::printable() const
00737 {
00738     return WvString("%s:%s", WvIPAddr::printable(), WvString(port));
00739 }
00740 
00741 
00742 /* Generate a struct sockaddr (suitable for sendto()) from this IP+Port
00743  * address.  Don't forget to delete it after you're done!
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     // nothing else needed
00791 }
00792 
00793 
00794 WvUnixAddr::~WvUnixAddr()
00795 {
00796     // nothing special
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 /* don't forget to delete the returned object when you're done! */
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) // appease valgrind
00821         max = sizeof(addr->sun_path) - 2;
00822     strncpy(addr->sun_path, sockname, max);
00823     if (addr->sun_path[0] == '@') // user wants an "abstract" socket
00824         addr->sun_path[0] = 0; // leading byte should be nul
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

Generated on Thu Aug 12 2010 11:33:09 for WvStreams by  doxygen 1.7.1