X-Git-Url: http://git.tdb.fi/?p=netvis.git;a=blobdiff_plain;f=source%2Faddress.cpp;fp=source%2Faddress.cpp;h=3a499716ec4720bfd24b8c297f25a3353bc6e977;hp=0000000000000000000000000000000000000000;hb=c1ea3cf06729622e2287e1604b1847d14fd2089c;hpb=597a794cd648dd7b4c9d442fdc39f5961a38aba0 diff --git a/source/address.cpp b/source/address.cpp new file mode 100644 index 0000000..3a49971 --- /dev/null +++ b/source/address.cpp @@ -0,0 +1,109 @@ +#include +#include +#include +#include +#include "address.h" + +using namespace std; + +Address::Address(): + type(0), + length(0), + mask_bits(0) +{ } + +Address::Address(uint32_t a): + type(ETH_P_IP), + length(4), + mask_bits(32) +{ + for(unsigned i=0; i<4; ++i) + data[i] = a>>(24-i*8); +} + +Address::Address(unsigned short t, const unsigned char *d, unsigned char l): + type(t), + length(l) +{ + copy(d, d+l, data); +} + +void Address::set_mask(const Address &mask) +{ + if(mask.length!=length) + throw invalid_argument("Address::set_mask"); + + mask_bits = 0; + for(unsigned i=0; (i>=1) + --mask_bits; + break; + } + } +} + +string Address::str() const +{ + if(type==ETH_P_IP) + { + char buf[INET_ADDRSTRLEN]; + return inet_ntop(AF_INET, data, buf, INET_ADDRSTRLEN); + } + else + return ""; +} + +unsigned Address::common_prefix_length(const Address &other) const +{ + if(length!=other.length) + return 0; + + unsigned prefix = 0; + for(unsigned i=0; i>=1) + --prefix; + break; + } + } + + return prefix; +} + +bool Address::masked_match(const Address &other) const +{ + unsigned prefix = common_prefix_length(other); + unsigned mask = min(mask_bits, other.mask_bits); + return prefix>=mask; +} + +void Address::to_sockaddr(sockaddr_storage &sa) const +{ + if(type==ETH_P_IP) + { + sockaddr_in &sa_in = reinterpret_cast(sa); + sa_in.sin_family = AF_INET; + sa_in.sin_port = 0; + sa_in.sin_addr.s_addr = *(uint32_t *)data; + } + else + throw runtime_error("Unknown type"); +} + +bool Address::operator<(const Address &other) const +{ + if(length!=other.length) + return length