1

ネットワーク通信システムコール(connect / sendto)の受信者情報を変更するJavaインターポーザー(LD_PRELOADメソッドを使用)を作成しています。

Javaが別のソケットに接続しようとするたびに、目的の受信者のIPとポートを変更します。JavaはIPv4マップIPv6アドレスを使用します。そのため、IPv4の部分を抽出する必要があります。リンクでNicolasBachschmidtによって規定された方法を使用してこれを達成します。

私が直面している問題は、すべてのIPv4マップIPv6アドレスについて、取得する結果文字列(IPv4部分)が常にであるということです0.0.0.110.0.0.1代わりに(for )である必要があります::ffff:10.0.0.1。私はこれを別のIPアドレスで試しました。結果は常に同じです。

私が言及したい2つのことは関連しているかもしれないと思います:

  1. 1か月前にローカルネットワーク(192.168.1.XXXIPアドレスを持つ)で同じプログラムをテストしたところ、プログラムは正しく機能していました。ポイントは(私は思いませんが)コードに問題があります。これを確認するために、スタックオーバーフローについて質問し、IPv4にマッピングされたIPv6アドレスをIPv4に変換しました。そのリンクについては前述しました)。

  2. 私は今、大学のネットワーク(10.XXX.XXX.XXXIPアドレスを持っている)と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);
}
4

1 に答える 1

0

@ugoren hex dump 手法 (コメント) のおかげで、IPv6 構造自体に0.0.0.1アドレスが含まれていることがわかりました。問題は異なるJDKが原因である可能性があることに気付きました。私が使用していたPCにはOpenJDK 6がありましたが、JavaプロジェクトはOpenJDK 7を使用してビルドされました。JDKをバージョン7に更新すると、エラーは消えました。ただし、まだ解決できない新しいスタックオーバーフローの質問に記載されている別のエラーが発生しました。

于 2012-06-28T07:20:30.077 に答える