Я пишу Java-интерполятор (используя метод LD_PRELOAD), который изменяет информацию получателя в сетевых системных вызовах (connect/sendto).Преобразование IPv6 в IPv4 дает только 0.0.0.1
Всякий раз, когда Java пытается подключиться к другому сокету, я изменяю предполагаемый IP-адрес получателя и порт. Java использует адреса IPv4-mapped-IPv6. Итак, мне нужно извлечь часть IPv4. Я достигаю этого, используя метод, предложенный Николасом Бахшмидтом в link.
Проблема, с которой я столкнулась, заключается в том, что для каждого IPv4-сопоставленного IPv6-адреса итоговая строка (часть IPv4), которую я получаю, всегда равна 0.0.0.1
. Вместо этого он должен быть 10.0.0.1
(для ::ffff:10.0.0.1
). Я пробовал это с разными IP-адресами. Результат всегда один и тот же.
Две вещи, которые я хотел бы упомянуть, что я думаю, что может быть связано с:
Когда я тестировал ту же программу, месяц назад в моей локальной сети (то есть
192.168.1.XXX
IP-адреса), программа работала правильно , Точка (я не думаю), есть проблема с кодом. Чтобы проверить это, я задал вопрос о stackoverflow для преобразования IPv4-сопоставленных IPv6-адресов в IPv4, ссылка на которые упоминается ранее).Я пытаюсь протестировать эту программу сейчас в моей университетской сети (у которой есть
10.XXX.XXX.XXX
IP-адреса) и VirtualBox (режим NAT, который также дает адреса10.XXX.XXX.XXX
). Однако в этих случаях я попытался подключиться к10.0.0.1
и12.0.0.1
. Оба дают0.0.0.1
.
Что я делаю неправильно?
UPDATE: В Java, подключение к сокету выполняется обычным способом:
Socket conn = new Socket("10.0.0.1", 50021);
Код для вставляю это подключить() системный вызов выглядит следующим образом:
int connect(int fd, const struct sockaddr *sk, socklen_t sl)
{
struct sockaddr_in *lsk_in = (struct sockaddr_in *) sk;
struct sockaddr_in6 *lsk_in6 = (struct sockaddr_in6 *) sk;
struct sockaddr_in addr4;
unsigned int len;
int nbytes, oport, tport, ret, i;
char ip_address[30];
char buffer[1024];
char tempBuffer[1024];
if((lsk_in->sin_family == AF_INET) || (lsk_in->sin_family == AF_INET6))
{
if(lsk_in->sin_family == AF_INET)
{
oport = ntohs(lsk_in->sin_port);
memcpy(&addr4.sin_addr.s_addr, &lsk_in->sin_addr.s_addr, sizeof(addr4.sin_addr.s_addr));
}
else if(lsk_in->sin_family == AF_INET6)
{
oport = ntohs(lsk_in6->sin6_port);
//This is where the problem is. I always get 0.0.0.1
memcpy(&addr4.sin_addr.s_addr, lsk_in6->sin6_addr.s6_addr+12, sizeof(addr4.sin_addr.s_addr));
}
memset(buffer, '\0', sizeof(buffer));
sprintf(buffer, "%s%c%s%c%i", NAT_VM_CONNECT_RULE, NAT_VM_DELIMITER, (char *)inet_ntoa(addr4.sin_addr), NAT_VM_DELIMITER, oport);
nbytes = send(sock, buffer, strlen(buffer), 0);
if(DEBUG_MODE)
fprintf(stdout, "[LD_INTERPOSER] Sent[%s]\n", buffer);
memset(buffer, '\0', sizeof(buffer));
nbytes = recv(sock, buffer, sizeof(buffer), 0);
fprintf(stderr, "[LD_INTERPOSER] Received CONNECT [%s]\n", buffer);
memset(ip_address, '\0', sizeof(ip_address));
int pos = strrchr(buffer, NAT_VM_DELIMITER) - buffer;
strncpy(ip_address, buffer, pos);
ip_address[pos] = '\0';
tport = atoi(buffer + pos + 1);
if(lsk_in->sin_family == AF_INET)
{
lsk_in->sin_addr.s_addr = inet_addr(ip_address + 7);
lsk_in->sin_port = htons(tport);
}
else if(lsk_in->sin_family == AF_INET6)
{
inet_pton(AF_INET6, ip_address, &(lsk_in6->sin6_addr));
lsk_in6->sin6_port = htons(tport);
}
fprintf(stderr, "[LD_INTERPOSER] IP[%s], Port[%d] for VM[%s]\n", ip_address, tport, vm_ip);
}
return real_connect(fd, sk, sl);
}
Никто не может вам помочь, если вы не покажете нам код, который вы написали до сих пор. – selbie
@selbie: Добавлен код. :) –
Вы проверили отдельные байты IPv6-адреса? Чтобы убедиться, что вы получили правильные байты (порядок байтов и т. Д.). –