The question is missing a lot of information. So, you are reading the server response from the SOCKS protocol. First, the buffer should not and should not have a fixed size of 10 bytes. It has 10 bytes if your address is IPv4 (which, as a general rule, was exhausted a few days ago, time to think about IPv6). If the source has an IPv6 address, the size of the server response is different.
From RFC 1928 , section 6, the server response has the following format:
+----+-----+-------+------+----------+----------+ |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT | +----+-----+-------+------+----------+----------+ | 1 | 1 | X'00' | 1 | Variable | 2 | +----+-----+-------+------+----------+----------+
Note that the address field is variable in size. For IPv4, in particular, ATYP == 0x01 and BND.ADDR are 4 in size, which makes 1 + 1 + 1 + 1 + 4 + 2 = 10 bytes. But you have to consider that other sizes are possible, especially if ATYP == 0x03, which makes BND.ADDR really variable in length.
So, answering your question, given that you have these bytes in the char buffer[] array (or pointer), you should first check the address type and then extract it as follows:
#include <arpa/inet.h> switch (buffer[3]) { case 0x01: { /* IPv4 address */ char result[INET_ADDRSTRLEN]; inet_ntop(AF_INET, (void*)(&buffer[4]), result, sizeof result); std::cout << "IPv4: " << result << "\n"; break; } case 0x04: { /* IPv6 address */ char result[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, (void*)(&buffer[4]), result, sizeof result); std::cout << "IPv6: " << result << "\n"; break; } default: std::cout << "Unsupported format.\n"; break; }
source share