ネットワーク通信システムコール(connect / sendto)の受信者情報を変更するJavaインターポーザー(LD_PRELOADメソッドを使用)を作成しています。
Javaが別のソケットに接続しようとするたびに、目的の受信者のIPとポートを変更します。JavaはIPv4マップIPv6アドレスを使用します。そのため、IPv4の部分を抽出する必要があります。リンクでNicolasBachschmidtによって規定された方法を使用してこれを達成します。
私が直面している問題は、すべてのIPv4マップIPv6アドレスについて、取得する結果文字列(IPv4部分)が常にであるということです0.0.0.1
。10.0.0.1
代わりに(for )である必要があります::ffff:10.0.0.1
。私はこれを別のIPアドレスで試しました。結果は常に同じです。
私が言及したい2つのことは関連しているかもしれないと思います:
1か月前にローカルネットワーク(
192.168.1.XXX
IPアドレスを持つ)で同じプログラムをテストしたところ、プログラムは正しく機能していました。ポイントは(私は思いませんが)コードに問題があります。これを確認するために、スタックオーバーフローについて質問し、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
。
私は何が間違っているのですか?
更新:Javaでは、ソケット接続は通常の方法で行われます。
Socket conn = new Socket("10.0.0.1", 50021);
このconnect()システムコールを挿入するコードは次のとおりです。
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);
}