Implemented IPv6 address decoding algorithm

master
Aadhavan Srinivasan 10 months ago
parent ae044c1905
commit cdd1db6808

@ -1,6 +1,7 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <vector> #include <vector>
#include <algorithm>
#include <iomanip> #include <iomanip>
#include <cstring> #include <cstring>
#include <cstdint> #include <cstdint>
@ -82,9 +83,12 @@ namespace connect_code {
std::string encode(std::string address, std::string port) { std::string encode(std::string address, std::string port) {
std::string addr_coded; std::string addr_coded = "";
/* Convert the address to decimal, and convert that to hex */
if (check_ip_ver(address.data()) == 4) { if (check_ip_ver(address.data()) == 4) {
/* First, convert the address into a decimal format. Then convert this decimal format
into base-32, and also convert the port number into base-32. Join these together with
a "_". */
/* I don't really have a reason to use my own function (dotted_dec_to_dec() /* I don't really have a reason to use my own function (dotted_dec_to_dec()
and dec_to_dotted_dec()), to convert the IP address from text to binary. and dec_to_dotted_dec()), to convert the IP address from text to binary.
The inet_pton() and inet_ntop() functions can do this just fine, and also The inet_pton() and inet_ntop() functions can do this just fine, and also
@ -101,10 +105,9 @@ namespace connect_code {
Then, tokenize the string, using colons as the delimiters. Then, tokenize the string, using colons as the delimiters.
Finally, take each token in the string, and convert it from base-16 to base-32, appending a '-' as a delimiter. */ Finally, take each token in the string, and convert it from base-16 to base-32, appending a '-' as a delimiter. */
std::string addr_expanded = expand_ip6_addr(address); std::string addr_expanded = expand_ip6_addr(address);
std::string addr_coded = "";
std::vector<std::string> addr_tokenized = tokenize_str(addr_expanded, ":"); std::vector<std::string> addr_tokenized = tokenize_str(addr_expanded, ":");
for (int i = 0; i < addr_tokenized.size()-1; i++ ) { for (size_t i = 0; i < addr_tokenized.size()-1; i++ ) {
addr_coded += base_convert(addr_tokenized[i], 16, 32); addr_coded += base_convert(addr_tokenized[i], 16, 32);
addr_coded += "-"; addr_coded += "-";
} }
@ -113,9 +116,6 @@ namespace connect_code {
/* TODO - Check if the IP address is actually converted properly, and test if the server socket is created correctly. /* TODO - Check if the IP address is actually converted properly, and test if the server socket is created correctly.
Also do the same for client side, and check client-server connection. */ Also do the same for client side, and check client-server connection. */
std::cout << addr_coded << std::endl;
abort();
} }
/* Convert the port to hex */ /* Convert the port to hex */
@ -127,32 +127,62 @@ namespace connect_code {
} }
std::vector<std::string> decode(std::string connect_code) { std::vector<std::string> decode(std::string connect_code) {
//<AIRPLANE_CODE> if (connect_code.find("_") == std::string::npos) {
throw std::invalid_argument("Invalid code entered."); // There must be an underscore, to separate the address part from the port part
}
int ip_ver = 0; int ip_ver = 0;
if (connect_code.find("-") == connect_code.npos) { if (connect_code.find("-") != std::string::npos) {
ip_ver = 6; // If the string contains hyphens, it must be an IPv6 address encoding. ip_ver = 6; // If the string contains hyphens, it must be an IPv6 address encoding.
} else { } else {
ip_ver = 4; ip_ver = 4;
} }
//</AIRPLANE_CODE>
if (connect_code.find("_") == std::string::npos) {
throw std::invalid_argument("Invalid code entered.");
}
std::vector<std::string> result = tokenize_str(connect_code, "_"); /* Split the string into address and port */ std::vector<std::string> result = tokenize_str(connect_code, "_"); /* Split the string into address and port */
std::string address = result[0]; /* Address (in base 16) */ std::string address = result[0]; /* Address (in base 32) */
std::string port = result[1]; /* Port (in base 16) */ std::string port = result[1]; /* Port (in base 32) */
std::vector<std::string> ret_val;
/* Base 16 to base 10 - These lines convert the string to a base 10 number, and convert the result back into a string */ /* The IPv6 and IPv4 encodings are slightly different - I use a hyphen as a delimiter
for IPv6, while there is no delimiter for IPv4. This is why I need to check if the address
is IPv4 or IPv6. */
if (ip_ver == 4) {
/* Base 32 to base 10 - These lines convert the string to a base 10 number, and convert the result back into a string */
address = std::to_string(std::stoul(address, 0, 32)); address = std::to_string(std::stoul(address, 0, 32));
port = std::to_string(std::stoul(port, 0, 32)); port = std::to_string(std::stoul(port, 0, 32));
/* Convert decimal address to dotted decimal */ /* Convert decimal address to dotted decimal */
address = dec_to_dotted_dec(address); address = dec_to_dotted_dec(address);
std::vector<std::string> ret_val; /* Create a vector containing the address and the port, which will be returned */
ret_val.push_back(address); ret_val.push_back(address);
ret_val.push_back(port); ret_val.push_back(port);
} else {
/* IPv6 */
/* There are three main steps to decoding for IPv6:
1. Tokenize the address using the delimiter set while encoding ('-', in my case).
2. Convert each token from base-32 to base-16.
3. Join the string vector back together into a string, this time using ':' as a delimiter. This will give us our IP address. */
std::string conv_addr = ""; // Stores the final address
std::vector<std::string> address_tokenized = tokenize_str(address, "-"); // Step 1
for (size_t i = 0; i < address_tokenized.size()-1; i++) {
address_tokenized[i] = base_convert(address_tokenized[i], 32, 16); // Step 2
conv_addr += address_tokenized[i] + ":"; // Step 3
}
conv_addr += base_convert(address_tokenized[address_tokenized.size()-1], 32, 16); // Add the last token
port = std::to_string(std::stoul(port, 0, 32));
std::cout << conv_addr << std::endl;
abort();
ret_val.push_back(conv_addr);
ret_val.push_back(port);
}
return ret_val; return ret_val;
} }
} }

Loading…
Cancel
Save