Много информации отсутствует в вопросе. Итак, вы читаете ответ сервера по протоколу SOCKS. Во-первых, буфер не должен иметь фиксированный размер 10 байт и не будет иметь его. Он имеет 10 байтов, если ваш адрес IPv4 (который по совпадению был исчерпан несколько дней назад, время подумать об IPv6). Если у источника есть адрес IPv6, размер ответа сервера будет другим.
С RFC 1928 , раздел 6, ответ сервера имеет следующий формат:
+----+-----+-------+------+----------+----------+
|VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
+----+-----+-------+------+----------+----------+
| 1 | 1 | X'00' | 1 | Variable | 2 |
+----+-----+-------+------+----------+----------+
Обратите внимание, что поле адреса имеет переменный размер. В частности, для IPv4 ATYP == 0x01 и BND.ADDR имеет размер 4, что составляет 1 + 1 + 1 + 1 + 4 + 2 = 10 байт. Но вы должны учитывать, что возможны другие размеры, особенно если ATYP == 0x03, что делает BND.ADDR действительно переменной длины.
Итак, отвечая на ваш вопрос, учитывая, что у вас есть эти байты в массиве (или указателе) char buffer[]
, вы должны сначала проверить тип адреса, а затем извлечь его следующим образом:
#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;
}