我正在编写一个Java内插器(使用LD_PRELOAD方法),它修改网络通信系统调用(connect/sendto)中的收件人信息。将IPv6转换为IPv4只给出0.0.0.1
每当Java尝试连接到另一个套接字,我修改预期的收件人IP和端口。 Java使用IPv4映射的IPv6地址。所以,我需要提取它的IPv4部分。我使用Nicolas Bachschmidt在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(也提供10.XXX.XXX.XXX
地址的NAT模式)上测试此程序。但是,在这些情况下,我尝试连接到10.0.0.1
和12.0.0.1
。两者都给0.0.0.1
。
我在做什么错?
更新:在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地址的单个字节?确保你得到正确的字节(字节顺序等)。 –