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!