简体   繁体   中英

TCP checksum for two structures

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!

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.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM