2012-06-28 2 views
1

Я пишу 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-адресами. Результат всегда один и тот же.

Две вещи, которые я хотел бы упомянуть, что я думаю, что может быть связано с:

  1. Когда я тестировал ту же программу, месяц назад в моей локальной сети (то есть 192.168.1.XXX IP-адреса), программа работала правильно , Точка (я не думаю), есть проблема с кодом. Чтобы проверить это, я задал вопрос о stackoverflow для преобразования IPv4-сопоставленных IPv6-адресов в IPv4, ссылка на которые упоминается ранее).

  2. Я пытаюсь протестировать эту программу сейчас в моей университетской сети (у которой есть 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); 
} 
+1

Никто не может вам помочь, если вы не покажете нам код, который вы написали до сих пор. – selbie

+0

@selbie: Добавлен код. :) –

+0

Вы проверили отдельные байты IPv6-адреса? Чтобы убедиться, что вы получили правильные байты (порядок байтов и т. Д.). –

ответ

0

Благодаря @ugoren (в комментариях), мне удалось выяснить, что сама структура IPv6 содержит адрес 0.0.0.1. Я понял, что проблема может быть связана с разными JDK. Проект Java был построен с использованием OpenJDK 7, в то время как ПК, который я использовал, имел OpenJDK 6. Когда я обновлял JDK до версии 7, ошибка исчезла. Тем не менее, он приземлился на другую ошибку, которая задокументирована на новом stackoverflow question, который я все еще не могу решить.

Смежные вопросы