11#include <sys/socket.h>
16#include <net/if_arp.h>
24#define ARPHRD_IPSEC 31
28typedef struct sockaddr sockaddr_bin;
31int WvEncap::extypes[] = {
33 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
54const char WvEncap::strings[][20] = {
75WvEncap::WvEncap(
int extype)
77 for (
int count=0; count < NUM_ENCAP_TYPES; count++)
79 if (extype == extypes[count])
90unsigned WvHash(
const WvAddr &addr)
99WvAddr *WvAddr::gen(
struct sockaddr *addr)
101 WvEncap encap(addr->sa_family);
105 case WvEncap::Loopback:
111 case WvEncap::ARCnet:
114 case WvEncap::Ethertap:
115 case WvEncap::Ethernet:
127bool WvAddr::isbroadcast()
const
133const unsigned char *WvAddr::rawdata()
const
139size_t WvAddr::rawdata_len()
const
145unsigned WvAddr::WvHash()
const
148 const unsigned char *cptr, *raw = rawdata();
149 int len = rawdata_len(), width;
151 if (!raw || !len)
return 0;
152 width = (
sizeof(hash)*8 / len) + 1;
154 for (cptr = raw; len; len--)
155 hash = (hash << width) ^ *(cptr++);
160bool WvAddr::comparator(
const WvAddr *a2,
bool first_pass)
const
162 if (type() != a2->type())
return false;
164 const unsigned char *raw1, *raw2;
168 if (len != a2->rawdata_len())
172 raw2 = a2->rawdata();
174 if (!raw1 && !raw2)
return true;
175 if (!raw1 || !raw2)
return false;
177 return !memcmp(raw1, raw2, len);
187WvStringAddr::WvStringAddr(
const struct sockaddr *_addr)
188 : addr((char *)_addr->sa_data), cap(_addr->sa_family)
193WvStringAddr::~WvStringAddr()
199WvEncap WvStringAddr::encap()
const
205const unsigned char *WvStringAddr::rawdata()
const
207 return (
const unsigned char *)(
const char *)addr;
211size_t WvStringAddr::rawdata_len()
const
217sockaddr_bin *WvStringAddr::sockaddr()
const
219 sockaddr_bin *sa =
new sockaddr_bin;
220 memset(sa, 0,
sizeof(*sa));
221 strncpy(sa->sa_data, addr,
sizeof(sa->sa_data));
226size_t WvStringAddr::sockaddr_len()
const
228 return sizeof(sockaddr_bin);
232WvString WvStringAddr::printable()
const
242void WvEtherAddr::string_init(
char const string[])
245 unsigned char *cptr = binaddr;
247 memset(binaddr, 0, ETHER_ADDR_LEN);
248 for (
unsigned int count=0; count < ETHER_ADDR_LEN; count++)
250 *cptr++ = strtoul(endptr ? endptr : string, &endptr, 16);
251 if (!endptr || !*endptr || endptr==
string)
break;
257WvEtherAddr::~WvEtherAddr()
264WvString WvEtherAddr::printable()
const
266 char s[ETHER_ADDR_LEN*3], *cptr = s;
268 for (
unsigned int count = 0; count < ETHER_ADDR_LEN; count++)
272 sprintf(cptr,
"%02X", binaddr[count]);
281WvEncap WvEtherAddr::encap()
const
283 return WvEncap(WvEncap::Ethernet);
288bool WvEtherAddr::isbroadcast()
const
290 for (
unsigned int count = 0; count < ETHER_ADDR_LEN; count++)
291 if (binaddr[count] != 0xFF)
297const unsigned char *WvEtherAddr::rawdata()
const
303size_t WvEtherAddr::rawdata_len()
const
305 return ETHER_ADDR_LEN;
309sockaddr_bin *WvEtherAddr::sockaddr()
const
311 sockaddr_bin *sa =
new sockaddr_bin;
312 memset(sa, 0,
sizeof(*sa));
313 sa->sa_family = ARPHRD_ETHER;
314 memcpy(sa->sa_data, binaddr, ETHER_ADDR_LEN);
319size_t WvEtherAddr::sockaddr_len()
const
321 return sizeof(sockaddr_bin);
325WvARCnetAddr::~WvARCnetAddr()
331WvString WvARCnetAddr::printable()
const
334 sprintf(s.edit(),
"%02X", binaddr);
339WvEncap WvARCnetAddr::encap()
const
341 return WvEncap(WvEncap::ARCnet);
345const unsigned char *WvARCnetAddr::rawdata()
const
351size_t WvARCnetAddr::rawdata_len()
const
357sockaddr_bin *WvARCnetAddr::sockaddr()
const
359 sockaddr_bin *sa =
new sockaddr_bin;
360 memset(sa, 0,
sizeof(*sa));
361 sa->sa_family = ARPHRD_ARCNET;
362 sa->sa_data[0] = binaddr;
367size_t WvARCnetAddr::sockaddr_len()
const
369 return sizeof(sockaddr_bin);
378void WvIPAddr::string_init(
const char string[])
380 const char *iptr, *nptr;
381 unsigned char *cptr = binaddr;
383 memset(binaddr, 0, 4);
385 for (
int count=0; count < 4 && nptr; count++)
388 nptr = strchr(iptr,
'.');
390 *cptr++ = strtol(iptr, NULL, 10);
400bool WvIPAddr::comparator(
const WvAddr *a2,
bool first_pass)
const
402 if (a2->type() == WVIPADDR)
403 return !memcmp(binaddr, ((
WvIPAddr *)a2)->binaddr,
sizeof(binaddr));
405 return a2->comparator(
this,
false);
408 const unsigned char *raw1, *raw2;
412 if (len != a2->rawdata_len())
416 raw2 = a2->rawdata();
418 if (!raw1 && !raw2)
return true;
419 if (!raw1 || !raw2)
return false;
421 return !memcmp(raw1, raw2, len);
430 binaddr[0], binaddr[1], binaddr[2], binaddr[3]);
437 unsigned char obin[4];
439 for (
int count=0; count<4; count++)
440 obin[count] = binaddr[count] & a2.binaddr[count];
448 unsigned char obin[4];
450 for (
int count=0; count<4; count++)
451 obin[count] = binaddr[count] | a2.binaddr[count];
459 unsigned char obin[4];
461 for (
int count=0; count<4; count++)
462 obin[count] = binaddr[count] ^ a2.binaddr[count];
468WvIPAddr WvIPAddr::operator~ ()
const
470 unsigned char obin[4];
472 for (
int count=0; count<4; count++)
473 obin[count] = ~binaddr[count];
481WvIPAddr WvIPAddr::operator+ (
int n)
const
483 uint32_t newad = htonl(ntohl(addr()) + n);
484 return WvIPAddr((
unsigned char *)&newad);
488WvIPAddr WvIPAddr::operator- (
int n)
const
490 uint32_t newad = htonl(ntohl(addr()) - n);
491 return WvIPAddr((
unsigned char *)&newad);
501const unsigned char *WvIPAddr::rawdata()
const
507size_t WvIPAddr::rawdata_len()
const
516sockaddr_bin *WvIPAddr::sockaddr()
const
518 sockaddr_in *sin =
new sockaddr_in;
520 memset(sin, 0,
sizeof(*sin));
521 sin->sin_family = AF_INET;
522 sin->sin_addr.s_addr = addr();
524 return (sockaddr_bin *)sin;
528size_t WvIPAddr::sockaddr_len()
const
530 return sizeof(sockaddr_in);
538 :
WvIPAddr(_net), mask(_net.netmask()) { }
542void WvIPNet::string_init(
const char string[])
548 maskptr = strchr(
string,
'/');
557 if (strchr(maskptr,
'.'))
561 bits = atoi(maskptr);
563 imask = htonl(~(((uint32_t)1 << (32-
bits)) - 1));
566 mask =
WvIPAddr((
unsigned char *)&imask);
580 imask = htonl(~(((uint32_t)1 << (32-
bits)) - 1));
583 mask =
WvIPAddr((
unsigned char *)&imask);
597 return WvIPAddr::printable();
603 return WvIPAddr::WvHash() + mask.WvHash();
607bool WvIPNet::comparator(
const WvAddr *a2,
bool first_pass)
const
609 if (a2->type() == WVIPNET)
610 return WvIPAddr::comparator(a2,
false) && mask == ((
WvIPNet *)a2)->mask;
612 return a2->comparator(
this,
false);
614 return WvIPAddr::comparator(a2,
false);
621 mask = mask & addr.mask & ~(*
this ^ addr);
627 return (addr.
base() & netmask()) == network() &&
628 (addr.netmask() & netmask()) == netmask();
635 uint32_t val = ntohl(mask.addr());
640 }
while ((val <<= 1) & (1 << 31));
646void WvIPNet::normalize()
650 uint32_t val = htonl(~(((uint32_t)1 << (32-
bits())) - 1));
651 mask =
WvIPAddr((
unsigned char *)&val);
658WvIPPortAddr::WvIPPortAddr()
664WvIPPortAddr::WvIPPortAddr(
const WvIPAddr &_ipaddr, uint16_t _port)
671static bool all_digits(
const char *s)
674 if (!isdigit((
unsigned char)*s))
681void WvIPPortAddr::string_init(
const char string[])
685 if (all_digits(
string))
692 const char *cptr = strchr(
string,
':');
694 cptr = strchr(
string,
' ');
696 cptr = strchr(
string,
'\t');
700 if (cptr && strcmp(cptr+1,
"0"))
705 struct servent *serv = getservbyname(cptr+1, NULL);
707 port = ntohs(serv->s_port);
715WvIPPortAddr::WvIPPortAddr(uint16_t _port)
722WvIPPortAddr::WvIPPortAddr(
const char string[], uint16_t _port)
729WvIPPortAddr::~WvIPPortAddr()
736WvString WvIPPortAddr::printable()
const
745sockaddr_bin *WvIPPortAddr::sockaddr()
const
747 sockaddr_in *sin = (sockaddr_in *)WvIPAddr::sockaddr();
748 sin->sin_port = htons(port);
749 return (sockaddr_bin *)sin;
753unsigned WvIPPortAddr::WvHash()
const
755 return WvIPAddr::WvHash() + port;
758bool WvIPPortAddr::comparator(
const WvAddr *a2,
bool first_pass)
const
760 if (a2->type() == WVIPPORTADDR)
761 return WvIPAddr::comparator(a2,
false)
764 return a2->comparator(
this,
false);
766 return WvIPAddr::comparator(a2,
false);
771WvUnixAddr::WvUnixAddr(
const char *_sockname)
772 : sockname(_sockname)
780 : sockname(_sockname)
787WvUnixAddr::WvUnixAddr(
const WvUnixAddr &_addr)
788 : sockname(_addr.sockname)
794WvUnixAddr::~WvUnixAddr()
800WvString WvUnixAddr::printable()
const
806WvEncap WvUnixAddr::encap()
const
808 return WvEncap::Unix;
813sockaddr_bin *WvUnixAddr::sockaddr()
const
815 sockaddr_un *addr =
new sockaddr_un;
817 memset(addr, 0,
sizeof(*addr));
818 addr->sun_family = AF_UNIX;
819 size_t max = strlen(sockname);
820 if (max >
sizeof(addr->sun_path) - 2)
821 max =
sizeof(addr->sun_path) - 2;
822 strncpy(addr->sun_path, sockname, max);
823 if (addr->sun_path[0] ==
'@')
824 addr->sun_path[0] = 0;
825 return (sockaddr_bin *)addr;
829size_t WvUnixAddr::sockaddr_len()
const
832 size_t max =
sizeof(fake->sun_path);
833 size_t val = strlen(sockname);
836 return sizeof(fake->sun_family) + val;
840const unsigned char *WvUnixAddr::rawdata()
const
842 return (
const unsigned char *)(
const char *)sockname;
846size_t WvUnixAddr::rawdata_len()
const
848 return strlen(sockname);
An ARCnet address is made up of a single hex number.
Base class for different address types, each of which will have the ability to convert itself to/from...
Common packet encapsulation types, with the ability to convert a Linux ARPHRD_* value or (struct sock...
An ethernet address is made up of a string of hex numbers, in the form AA:BB:CC:DD:EE:FF.
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
An IP address is made up of a "dotted quad" – four decimal numbers in the form www....
An IP network comprises two WvIPAddr structures: an address and a netmask.
bool includes(const WvIPNet &addr) const
determine whether the given address is already included in this net
void include(const WvIPNet &addr)
adjust the netmask so that 'addr' would be included in this network
WvIPNet()
construct an empty IPNet for later copying (probably by operator=)
int bits() const
weird netmasks such as 255.0.255.0 (easy example) are almost never used – they have '0' bits in the m...
virtual unsigned WvHash() const
Override the hash and comparison functions.
WvIPAddr base() const
Get the 'base IP address' component, netmask, network, and broadcast.
An IP+Port address also includes a port number, with the resulting form www.xxx.yyy....
A WvAddr that simply contains a printable string with a user-defined encapsulation type.
WvString is an implementation of a simple and efficient printable-string class.
A Unix domain socket address is really just a filename.