ip man
This commit is contained in:
parent
e98512193f
commit
cd85c3763d
2 changed files with 173 additions and 3 deletions
|
@ -1,5 +1,141 @@
|
||||||
#include "net.hpp"
|
#include "net.hpp"
|
||||||
|
|
||||||
|
// BEGIN IPADDRESS CLASS
|
||||||
|
|
||||||
|
sosc::net::IpAddress::IpAddress() {
|
||||||
|
for(int i = 0; i < 8; ++i)
|
||||||
|
this->parts[i] = std::make_pair(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sosc::net::IpAddress::Parse(const std::string& addr) {
|
||||||
|
std::string addr_trim = str::trim(addr);
|
||||||
|
|
||||||
|
auto parts = str::split(addr_trim, '.');
|
||||||
|
if(parts.size() == 4)
|
||||||
|
return ParseIPv4Parts(parts);
|
||||||
|
else if(parts.size() != 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
parts = str::split(addr_trim, "::");
|
||||||
|
if(parts.size() == 1) {
|
||||||
|
if(ParseIPv6Part(parts[0], true) != 8)
|
||||||
|
return false;
|
||||||
|
} else if(parts.size() == 2) {
|
||||||
|
int left_cnt, right_cnt;
|
||||||
|
if((left_cnt = ParseIPv6Part(parts[0], true)) == -1)
|
||||||
|
return false;
|
||||||
|
if((right_cnt = ParseIPv6Part(parts[1], false)) == -1)
|
||||||
|
return false;
|
||||||
|
if(left_cnt + right_cnt > 8)
|
||||||
|
return false;
|
||||||
|
} else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sosc::net::IpAddress::ParseIPv4Parts
|
||||||
|
(const std::vector<std::string>& parts)
|
||||||
|
{
|
||||||
|
this->parts[5] = std::make_pair(0xFFFF, 0);
|
||||||
|
for(int i = 0; i < 4; ++i) {
|
||||||
|
addrpart_t* ptr = &(this->parts[i < 2 ? 6 : 7]);
|
||||||
|
std::string part = str::trim(parts[i]);
|
||||||
|
int part_int;
|
||||||
|
|
||||||
|
if(part == "")
|
||||||
|
return false;
|
||||||
|
else if(part == "*") {
|
||||||
|
part_int = 0;
|
||||||
|
ptr->second |= (i % 2 == 0) ? 0xC : 0x3;
|
||||||
|
} else {
|
||||||
|
try { part_int = std::stoi(part); }
|
||||||
|
catch(...) { return false; }
|
||||||
|
}
|
||||||
|
|
||||||
|
if(part_int < 0 || part_int > 255)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ptr->first |= (i % 2 == 0)
|
||||||
|
? part_int << 8
|
||||||
|
: part_int;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sosc::net::IpAddress::ParseIPv6Part
|
||||||
|
(const std::string& addr_part, bool from_start)
|
||||||
|
{
|
||||||
|
if(str::trim(addr_part) == "")
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
auto parts = str::split(addr_part, ':');
|
||||||
|
if(parts.size() > 8)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for(int i = 0; i < parts.size(); ++i) {
|
||||||
|
addrpart_t* ptr =
|
||||||
|
&(this->parts[from_start ? i : 8 - parts.size() + i]);
|
||||||
|
std::string part = str::trim(parts[i]);
|
||||||
|
int part_len = part.length();
|
||||||
|
if(part_len > 4 || part_len == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if(part == "*") {
|
||||||
|
ptr->first = 0;
|
||||||
|
ptr->second = 0x0F;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < part_len; ++i) {
|
||||||
|
if(part[i] == '*') {
|
||||||
|
part[i] = '0';
|
||||||
|
ptr->second |= 1 << (part_len - i - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try { ptr->first = std::stoi(part, NULL, 16); }
|
||||||
|
catch(...) { return -1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
return parts.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
sosc::net::IpAddress::operator std::string () const {
|
||||||
|
return this->ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
sosc::net::IpAddress::operator const char* () const {
|
||||||
|
return this->ToString().c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string sosc::net::IpAddress::ToString(bool force_ipv6) const {
|
||||||
|
return "TODO THIS";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sosc::net::IpAddress::IsIdentical(const IpAddress& rhs) const {
|
||||||
|
for(int i = 0; i < 8; ++i)
|
||||||
|
if(this->parts[i] != rhs.parts[i])
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sosc::net::IpAddress::IsIPv4() const {
|
||||||
|
auto blank = std::make_pair<uint16_t, uint8_t>(0, 0);
|
||||||
|
for(int i = 0; i < 5; ++i)
|
||||||
|
if(this->parts[i] != blank)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(this->parts[5] != std::make_pair<uint16_t, uint8_t>(0xFFFF, 0))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// END IPADDRESS CLASS
|
||||||
|
|
||||||
bool sosc::net::is_big_endian() {
|
bool sosc::net::is_big_endian() {
|
||||||
static uint16_t check = 0xFF00;
|
static uint16_t check = 0xFF00;
|
||||||
if(check == 0xFF00)
|
if(check == 0xFF00)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include "string.hpp"
|
||||||
|
|
||||||
#undef HTONS
|
#undef HTONS
|
||||||
#undef HTONUS
|
#undef HTONUS
|
||||||
|
@ -40,12 +41,45 @@ namespace sosc {
|
||||||
namespace net {
|
namespace net {
|
||||||
class IpAddress {
|
class IpAddress {
|
||||||
public:
|
public:
|
||||||
|
// all strings taken as arguments will accept both IPv4 and IPv6 addrs
|
||||||
|
// IPv4 addrs will be stored as IPv6 in this format:
|
||||||
|
// 127.126.0.255
|
||||||
|
// -> ::FFFF:7F7E:FF
|
||||||
|
// ^ ^ ^ ^
|
||||||
|
// |--|-|-|----- UNIQUE PREFIX VALUE (decimal 65535)
|
||||||
|
// |-|-|----- FIRST OCTET AS HEXADECIMAL (127 -> 7F)
|
||||||
|
// |-|----- SECOND OCTET AS HEXADECIMAL (126 -> 7E)
|
||||||
|
// |---+- THIRD OCTET IS HIDDEN SINCE FOURTH IS LOWER
|
||||||
|
// +- (0.255 -> 00FF -{equiv. to}-> FF)
|
||||||
|
|
||||||
|
IpAddress();
|
||||||
|
bool Parse(const std::string& addr);
|
||||||
|
|
||||||
|
operator std::string () const;
|
||||||
|
operator const char* () const;
|
||||||
|
std::string ToString(bool force_ipv6 = false) const;
|
||||||
|
|
||||||
|
bool operator == (const IpAddress& rhs) const;
|
||||||
|
bool operator != (const IpAddress& rhs) const;
|
||||||
|
|
||||||
|
bool IsIdentical(const IpAddress& rhs) const;
|
||||||
|
bool IsIPv4() const;
|
||||||
private:
|
private:
|
||||||
typedef std::pair<uint16_t, uint8_t> addrpart_t;
|
// pair item 1 is the two bytes in an IPv6 address
|
||||||
addrpart_t parts[8] = {};
|
// pair item 2 is a wildcard bitmask on the nibble in the address
|
||||||
|
// 4 msbits unused, 4 lsbits indicate wildcards if bit is set
|
||||||
|
// ex. ::F F F F (IPv6 address)
|
||||||
|
// 0 1 1 0 (bitmask)
|
||||||
|
// 4 3 2 1 (bit position where 1 is LSB)
|
||||||
|
// would treat the middle two nibbles as wildcards; so this ip
|
||||||
|
// would match eg. ::F00F, ::FAAF, ::FEAF etc.
|
||||||
|
|
||||||
static addrpart_t ParsePart(std::string part);
|
typedef std::pair<uint16_t, uint8_t> addrpart_t;
|
||||||
|
std::string tostr_cache;
|
||||||
|
addrpart_t parts[8];
|
||||||
|
|
||||||
|
bool ParseIPv4Parts(const std::vector<std:string>& parts);
|
||||||
|
int ParseIPv6Part(const std::string& addr_part, bool from_start);
|
||||||
};
|
};
|
||||||
|
|
||||||
bool is_big_endian();
|
bool is_big_endian();
|
||||||
|
|
Loading…
Reference in a new issue