Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4070064

icmp ECHOREPLY packet can not be received, recvfrom() in my C program not work

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 1.1.6
    • 1.1.1, 1.1.3, 1.1.4, 1.1.5
    • hotspot
    • 1.1.6
    • generic, x86, sparc
    • solaris_2.5.1, windows_nt
    • Verified



        Name: rlT66838 Date: 08/06/97


        Hi:

        I use native method to implement a ping() for java. my problem is:
        I used super user mode in my Sun Sparc 5 station, when I ping a remote host
        (a host not in our LAN, i.e: 129.79.250.121),
        then no any icmp packet come back. However, If I ping a local host (in
        out LAN) , then it works fine.

        I also found this problem will only happen when I use jdk 1.1.2 and 1.1.3.
        for solaris 2.4 and 2.5. If I use jdk 1.02, 1.1, and 1.1.1 for Solaris,
        it works fine too. I also ported this source code to Windows NT 4.0,
        my code also works fine for jdk 1.1.1, 1.1.2, and 1.1.3 for NT 4.0 versions.

        the steps of compile.
        1) javac Ping.java
        2) javah Ping
        3) javah -stubs Ping
        then Ping.c and Ping.h are generated.

        I copy the prototype of the native methods from
        Ping.h to my PingImpl.c. I put my implementation
        to PingImpl.c file. The compilation is done success and
        works fine for Windows NT 4.0 and Solaris 2.4 except
        when I ping a remote host.

        my problem is:
        1) when I used JDK 1.02, 1.1, and 1.1.1, such source code is working.
           but if I used jdk 1.1.2 and 1.1.3, problem happened. the problems
           is after sendto() sent out an icmp ECHO request packet, the recvfrom()
           is blocking there because the icmp ECHOREPLY packet does not come
           back to the recvfrom() call. But it works fine when I use jdk 1.1.1
           and jdk 1.02 in Solaris 2.4.

        2) The same source code (porting to Windows NT 4.0) with all jdk versions
           (1.1.1, 1.1.2, and 1.1.3) working fine

        a portion of my source code is listed as follows:

        /*--- in PingImpl.c ---- */
        long Ping_pingHost(struct HPing * this, struct Hjava_lang_String *hostName,
        long timeout)
        {
        .
        .
        .

        memset(&saDestAddr,0,sizeof(struct sockaddr));
        saDestAddr.sin_family = AF_INET;
                  
        if ((saDestAddr.sin_addr.s_addr = inet_addr(szRemoteHost)) == INADDR_NONE) {
        if (!(pHostEntry = (struct hostent *)gethostbyname(szRemoteHost))) {
        printf("can't get \"%s\" host entry.",szRemoteHost);
        return (long)FALSE;
        } else {
        saDestAddr.sin_family = pHostEntry->h_addrtype;
        memcpy((char *)&saDestAddr.sin_addr, (char *)(pHostEntry->h_addr),
        pHostEntry->h_length);
        }
        }

        /* open a socket */
        if ((proto = getprotobyname("icmp")) == NULL)
        printf("error in get protocol for socket\n");

        if ((ping_socket=socket(saDestAddr.sin_family, SOCK_RAW, proto->p_proto)) < 0) {
        printf("can't create raw socket error, ping_socket = %d\n", ping_socket);
        return (long)FALSE;
             }

        memset(&recvResult,0,sizeof(recvResult));

        if (icmp_send_ping(ping_socket, &saDestAddr, szMsgBuf, SIZE_ICMP_HDR,
        process_id))
        {
        icmp_recv_ping(ping_socket, szString, TRUE, process_id, (int)timeout);
        .
        .
        }
        .
        .
        }

        int icmp_send_ping(SOCKET sockfd, struct sockaddr_in *toAddress,
                  char * pPacket,int nLength, int processID)
        {
        int result;
        int dataLength;
        struct icmp *icmp;

        dataLength = nLength + SIZE_ICMP_HDR;
        icmp = (struct icmp *)pPacket;

        /* complete the ICMP packet header */
        icmp->icmp_type = 8; /* define ICMP_ECHOREQ = 8 */
        icmp->icmp_code = 0;
        icmp->icmp_cksum = 0;
        icmp->icmp_id = processID;
        icmp->icmp_seq = nTransmitted;

        /* get time and check sum
        /* send the packet */
        if ((result = sendto(sockfd, pPacket, dataLength, 0,
        (struct sockaddr *)toAddress,
        sizeof(struct sockaddr))) == -1)
        {
        .
        .
        .
        }
        }

        void icmp_recv_ping(SOCKET sockfd, char *szRecvPkt,int bPrintFlag, int processID,
        int timing)
        {
        int nBytesRecv;
        int saFromAddrLen;
        struct sockaddr_in saFromAddr;

        saFromAddrLen = sizeof(saFromAddr);

        saFromAddr.sin_family = AF_INET;
        saFromAddr.sin_addr.s_addr = INADDR_ANY;
        saFromAddr.sin_port = 0;
        .
        .
        .

        printf("before recvfrom()\n");
        nBytesRecv = recvfrom(sockfd, szRecvPkt, MAXPACKET, 0,
        (struct sockaddr *)&saFromAddr,
        (int *)&saFromAddrLen);
        printf("after recvfrom()\n");
        .
        .
        .
        }
        /* ----------------------------------------- */



        ======================================================================

              never Tom Rodriguez
              rlewis Roger Lewis (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: