1

I'm trying to recode ping command in C as educational purpose. The ICMP sending seems OK (I compared it to original ping on wireshark) but on IP packet reception I have the following problem:

The 16 bits of total length in IP header are different from what I see on wireshark. I use recvmsg() function to receive data in a buffer as below.

UPDATE: I do have this behavior on macos but not on a linux VM

    struct msghdr msg;
    struct iovec iov[1];
    char databuf[1000];
    char datacontrol[1000];

    bzero(&(msg), sizeof(msg));
    bzero(&(iov), sizeof(iov));
    bzero(&(databuf), sizeof(databuf));
    bzero(&(datacontrol), sizeof(datacontrol));


    msg.msg_name = env->addr->ai_addr;
    msg.msg_namelen = env->addr->ai_addrlen;
    iov[0].iov_base = &(databuf[0]);
    iov[0].iov_len = sizeof(databuf);
    msg.msg_iov = iov;
    msg.msg_iovlen = 1;
    msg.msg_control = &(datacontrol[0]);
    msg.msg_controllen = sizeof(datacontrol);
    msg.msg_flags = 0;

    int retrecv = recvmsg(env.sockfd, &(msg), MSG_WAITALL);

When I display the data I receive in databuf as below:

    for (int i = 0; i < 20; i++)
    {
        for (int j = 7; j >= 0; j--)
            printf("%d", ((databuf[i] >> j) & 1));
        printf("  ");
        if (i == 7 || i == 15)
            printf("\n");
    }

I have this as result:

01000101  00000000  01000000  00000000  00000000  00000000  00000000  00000000
01110100  00000001  11010111  00110011  11011000  00111010  11010101  01001110  
11000000  10101000  00000001  01000100

when currently on wireshark I have:

01000101  00000000  00000000  01010100  00000000  00000000  00000000  00000000
01110100  00000001  11010111  00110011  11011000  00111010  11010101  01001110  
11000000  10101000  00000001  01000100

All bits are same except the 3th and 4th (total length of IP packet). I'm aware of little/big endian issue but I don't understand the difference there.

Thank you !

Alex
  • 11
  • 2
  • 1
    Unrelated to your problem, but semantically your usage of the address-of operator `&` for arrays is incorrect. You should pass a pointer to the first element, not a pointer to the array. For example, plain `databuf` by itself will *decay* to a pointer to its first element, i.e. `&databuf[0]`, which have the type `char *`. When you use `&databuf` you get a pointer to the array itself, which have the type `char (*)[1000]`. Yo're lucky that both are pointing to the same location, but as I said they're semantically different due to the difference in type. – Some programmer dude Jan 20 '21 at 12:33
  • True! I didn't notice but I changed it. Thank you! – Alex Jan 20 '21 at 14:01

0 Answers0