Здравствуйте, помогите пожалуйста с рассчетом контрольной суммы IP, TCP.
Предисловие:
Сейчас изучаю netgraph.
Хочу написать модуль, который в проходящих через него пакеты меняет IP адреса источника и назначения местами.
На машине стоит Ubuntu, на ней виртуалка с FreeBSD.
В сеть посылаю пакеты tcpreplay'ем, которые сохранил на Ubuntu с помощью tcpdump(пакеты посылал с виртуалки ping'ом).
На виртуалке сетевые интерфейсы стоят в promisc режиме.
Перед попаданием на интерфейс пакет проходит через мой модуль.Собственно, сами вопросы:
1) Могу ли я рассчитывать этой функцией контрольную сумму для IP и для TCP?
Функция для подсчета контрольной суммы:
static unsigned short сsum (unsigned short *ptr, int len)
{
register int sum = 0;
while (len > 1)
{
sum += *ptr++;
len -= 2;
}
if (len == 1)
sum += *((unsigned char *) ptr);
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return (~sum);
}
2) Правильно ли я рассчитываю контрольную сумму IP?
Для замены IP определена функция:
#define xchg(a,b,type) do { type t; t=a; a=b; b=t;} while (0)
В пакете меняю ip местами следующим образом:
struct mbuf *m;
struct ip *ip;
ip = mtod(m, struct ip *);
xchg(ip->ip_dst.s_addr, ip->ip_src.s_addr, u_int32_t);
Далее посдсчитываю контрольную сумму ip:
ip-ip_sum=0;
ip->ip_sum=сsum((unsigned short *)ip, sizeof(struct ip));
3)С подсчетом контрольной суммы TCP я не очень разобрался. Правильно ли я понял, что для подсчета контрольной суммы TCP используется псевдозаголовок и TCP заголовок + данные?
Для начала я заполняю псевдозаголовок:
struct ippseudo ippseudo;
ippseudo->ippseudo_src = ip->ip_src;
ippseudo->ippseudo_dst = ip->ip_dst;
ippseudo->ippseudo_pad = 0;
ippseudo->ippseudo_p = IPPROTO_TCP;
ippseudo->ippseudo_len = htons(sizeof(struct tcphdr));
4)Правильно ли я определяю указатель на заголовок TCP?
struct tcphdr *th;
th=(struct tcphdr *)((caddr_t)ip+(ip->ip_hl <<2));
5) Что нужно подать на функцию csum, что бы правильно рассчитать контрольную сумму TCP?