0

I am trying to make a function that generates checksums for TCP, but I work with two structures of TCP, because the tcphdr structure made for Mac OS X in tcp.h header does not contain everything that I need to make a packet. My packet contains the tcphdr structure and this structure:

typedef struct tcp_option{
   u_int16_t mss_opt:8,
             mss_len:8;
   u_int16_t mss;
   u_int16_t sack_kind:8,
             sack_len:8;
   u_int16_t win_opt:8,
             win_len:8;
   u_int32_t win:8,
             win_nop:8,
             time_opt:8,
             time_len:8;
   u_int32_t time;
   u_int32_t time_echo;
} tcp_option;

So does anyone have an idea to make a checksum to pass this structure and the tcphdr structure to.

My checksum function works for the IP checksum, but not for the TCP checksum with two structures in it. This is the checksum function:

unsigned short checksum(const char *buf, unsigned size)
{
    unsigned long long sum = 0;
    const unsigned long long *b = (unsigned long long *) buf;

    unsigned t1, t2;
    unsigned short t3, t4;

    /* Main loop - 8 bytes at a time */
    while (size >= sizeof(unsigned long long))
    {
        unsigned long long s = *b++;
        sum += s;
        if (sum < s) sum++;
        size -= 8;
    }

    /* Handle tail less than 8-bytes long */
    buf = (const char *) b;
    if (size & 4)
    {
        unsigned s = *(unsigned *)buf;
        sum += s;
        if (sum < s) sum++;
        buf += 4;
    }

    if (size & 2)
    {
        unsigned short s = *(unsigned short *) buf;
        sum += s;
        if (sum < s) sum++;
        buf += 2;
    }

    if (size)
    {
        unsigned char s = *(unsigned char *) buf;
        sum += s;
        if (sum < s) sum++;
    }

    /* Fold down to 16 bits */
    t1 = sum;
    t2 = sum >> 32;
    t1 += t2;
    if (t1 < t2) t1++;
    t3 = t1;
    t4 = t1 >> 16;
    t3 += t4;
    if (t3 < t4) t3++;

    return ~t3;
}

Didn't made it myself, I stole it from the internet.

SOLUTION: I removed the two structures and combined it to one structure, then I made an pseudo header structure which I used to make an checksum!

John John
  • 35
  • 6
  • What is the problem with your current approach? (error code, compilation error, wrong output, etc.) You haven't specified what the problem is. – user694733 Feb 15 '18 at 15:13
  • Checksum is not valid. I used Wireshark to check the output. So wrong output. – John John Feb 15 '18 at 15:15
  • [Edit] your question and include necessary information regarding your problem (see [mcve]). People cannot help you if they can't see where the problem is. – user694733 Feb 15 '18 at 15:17
  • The only problem is that I don't know how to pass two structures to an checksum for 1 TCP header – John John Feb 15 '18 at 15:19

1 Answers1

0

Your structure has an odd number of u_int_16_t members before the u_int_32_t members, so in order to assure the 32-bit members are aligned properly it will have a hidden 16-bit chunk in it that you will never be able to set by member reference, and the contents of which will be undefined. Thus comparing every 16-bit word in your buffer will include comparing that 16-bit value. If you don't use some method to make sure the value of that space is always the same, like memset(0) the structure before assigning values to its members, then you will have to use a different comparison process (compare the members explicitly.)

Whilom Chime
  • 366
  • 1
  • 9