11 #include <sys/socket.h>
14 #include <sys/types.h>
16 #include <net/if_arp.h>
24 #define ARPHRD_IPSEC 31
28 typedef struct sockaddr sockaddr_bin;
31 int WvEncap::extypes[] = {
33 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
54 const char WvEncap::strings[][20] = {
75 WvEncap::WvEncap(
int extype)
77 for (
int count=0; count < NUM_ENCAP_TYPES; count++)
79 if (extype == extypes[count])
90 unsigned WvHash(
const WvAddr &addr)
99 WvAddr *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:
127 bool WvAddr::isbroadcast()
const
133 const unsigned char *WvAddr::rawdata()
const
139 size_t WvAddr::rawdata_len()
const
145 unsigned 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++);
160 bool 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);
187 WvStringAddr::WvStringAddr(
const struct sockaddr *_addr)
188 : addr((char *)_addr->sa_data), cap(_addr->sa_family)
193 WvStringAddr::~WvStringAddr()
199 WvEncap WvStringAddr::encap()
const
205 const unsigned char *WvStringAddr::rawdata()
const
207 return (
const unsigned char *)(
const char *)addr;
211 size_t WvStringAddr::rawdata_len()
const
217 sockaddr_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));
226 size_t WvStringAddr::sockaddr_len()
const
228 return sizeof(sockaddr_bin);
232 WvString WvStringAddr::printable()
const
242 void 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;
257 WvEtherAddr::~WvEtherAddr()
264 WvString 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]);
281 WvEncap WvEtherAddr::encap()
const
283 return WvEncap(WvEncap::Ethernet);
288 bool WvEtherAddr::isbroadcast()
const
290 for (
unsigned int count = 0; count < ETHER_ADDR_LEN; count++)
291 if (binaddr[count] != 0xFF)
297 const unsigned char *WvEtherAddr::rawdata()
const
303 size_t WvEtherAddr::rawdata_len()
const
305 return ETHER_ADDR_LEN;
309 sockaddr_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);
319 size_t WvEtherAddr::sockaddr_len()
const
321 return sizeof(sockaddr_bin);
325 WvARCnetAddr::~WvARCnetAddr()
331 WvString WvARCnetAddr::printable()
const
334 sprintf(s.edit(),
"%02X", binaddr);
339 WvEncap WvARCnetAddr::encap()
const
341 return WvEncap(WvEncap::ARCnet);
345 const unsigned char *WvARCnetAddr::rawdata()
const
351 size_t WvARCnetAddr::rawdata_len()
const
357 sockaddr_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;
367 size_t WvARCnetAddr::sockaddr_len()
const
369 return sizeof(sockaddr_bin);
378 void 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);
395 WvIPAddr::~WvIPAddr()
400 bool 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);
427 WvString WvIPAddr::printable()
const
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];
468 WvIPAddr WvIPAddr::operator~ ()
const
470 unsigned char obin[4];
472 for (
int count=0; count<4; count++)
473 obin[count] = ~binaddr[count];
481 WvIPAddr WvIPAddr::operator+ (
int n)
const
483 uint32_t newad = htonl(ntohl(addr()) + n);
484 return WvIPAddr((
unsigned char *)&newad);
488 WvIPAddr WvIPAddr::operator- (
int n)
const
490 uint32_t newad = htonl(ntohl(addr()) - n);
491 return WvIPAddr((
unsigned char *)&newad);
495 WvEncap WvIPAddr::encap()
const
501 const unsigned char *WvIPAddr::rawdata()
const
507 size_t WvIPAddr::rawdata_len()
const
516 sockaddr_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;
528 size_t WvIPAddr::sockaddr_len()
const
530 return sizeof(sockaddr_in);
538 :
WvIPAddr(_net), mask(_net.netmask()) { }
542 void 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();
607 bool 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));
646 void WvIPNet::normalize()
650 uint32_t val = htonl(~(((uint32_t)1 << (32-
bits())) - 1));
651 mask =
WvIPAddr((
unsigned char *)&val);
658 WvIPPortAddr::WvIPPortAddr()
664 WvIPPortAddr::WvIPPortAddr(
const WvIPAddr &_ipaddr, uint16_t _port)
671 static bool all_digits(
const char *s)
674 if (!isdigit((
unsigned char)*s))
681 void 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);
715 WvIPPortAddr::WvIPPortAddr(uint16_t _port)
722 WvIPPortAddr::WvIPPortAddr(
const char string[], uint16_t _port)
729 WvIPPortAddr::~WvIPPortAddr()
736 WvString WvIPPortAddr::printable()
const
745 sockaddr_bin *WvIPPortAddr::sockaddr()
const
747 sockaddr_in *sin = (sockaddr_in *)WvIPAddr::sockaddr();
748 sin->sin_port = htons(port);
749 return (sockaddr_bin *)sin;
753 unsigned WvIPPortAddr::WvHash()
const
755 return WvIPAddr::WvHash() + port;
758 bool 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);
771 WvUnixAddr::WvUnixAddr(
const char *_sockname)
772 : sockname(_sockname)
780 : sockname(_sockname)
787 WvUnixAddr::WvUnixAddr(
const WvUnixAddr &_addr)
788 : sockname(_addr.sockname)
794 WvUnixAddr::~WvUnixAddr()
800 WvString WvUnixAddr::printable()
const
806 WvEncap WvUnixAddr::encap()
const
808 return WvEncap::Unix;
813 sockaddr_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;
829 size_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;
840 const unsigned char *WvUnixAddr::rawdata()
const
842 return (
const unsigned char *)(
const char *)sockname;
846 size_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.