Здравствуйте, alexora, Вы писали:

A>Как это неправильная сумма ?

A>Ты для tcp отдельно считаешь и для ip отдельно ?

я уже ничего не считаю, времени нету на это
а контрольная сумма для TCP считается вот как (см. RFC 793):
    0                   1                   2                   3   
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |          Source Port          |       Destination Port        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                        Sequence Number                        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Acknowledgment Number                      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Data |           |U|A|P|R|S|F|                               |
   | Offset| Reserved  |R|C|S|S|Y|I|            Window             |
   |       |           |G|K|H|T|N|N|                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |           Checksum            |         Urgent Pointer        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Options                    |    Padding    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                             data                              |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                +--------+--------+--------+--------+
                |           Source Address          |
                +--------+--------+--------+--------+
                |         Destination Address       |
                +--------+--------+--------+--------+
                |  zero  |  PTCL  |    TCP Length   |
                +--------+--------+--------+--------+

Поле контрольной суммы — это 16-битное дополнение суммы всех 16- битных слов заголовка и текста. Если сегмент содержит в заголовке и тексте нечетное количество октетов, подлежащих учету в контрольной сумме, последний октет будет дополнен нулями справа с тем, чтобы образовать для предоставления контрольной сумме 16-битное слово. Возникший при таком выравнивании октет не передается вместе с сегментом по сети. Перед вычислением контрольной суммы поле этой суммы заполняется нулями.

Контрольная сумма, помимо всего прочего, учитывает 96 бит псевдозаголовка, который для внутреннего употребления ставится перед TCP заголовком. Этот псевдозаголовок содержит адрес отправителя, адрес получателя, протокол и длину TCP сегмента. Такой подход обеспечивает защиту протокола TCP от ошибшихся в маршруте сегментов. Эту информацию обрабатывает Internet протокол. Она передается через интерфейс протокол TCP/локальная сеть в качестве аргументов или результатов запросов от протокола TCP к протоколу IP.

Длина TCP сегмента — это длина TCP заголовка и поля данных, измеренная в октетах. Это не является точным указанием количества передаваемых по сети октетов, она не учитывает 12 октетов псевдозаголовка, но тем не менее расчет этого параметра все же производится.

Функция для подсчёта, уже как-то приводилась мною, но поиск не работает :
unsigned short CalculateChecksum(unsigned short *usBuf, int iSize)
{
    unsigned long usChksum=0;
    while (iSize>1)
    {
        usChksum+=*usBuf++;
        iSize-=sizeof(unsigned short);
    }

    if (iSize)
        usChksum+=*(unsigned char*)usBuf;

    usChksum=(usChksum >> 16) + (usChksum & 0xffff);
    usChksum+=(usChksum >> 16);

    return (unsigned short)(~usChksum);
}

1. Заполняешь структуру псевдозаголовка:
  • адрес назначения
  • адрес источника
  • ноль
  • протокол
  • длина пакета
2. добаваляешь к буферу в котором находится эта структура, буфер с твоим заголовком и данными (поле суммы = 0)
3. считаешь контрольную сумму выше приведённой функцией (это будет контрольная сумма TCP заголовка)
4. формируешь структуру IP заголовка
5. считаешь сумму заголовка IP (это по RFC, но я видел в программах, что считается сумма по всему пакету и вроде как работает..)
6. на сколько я помню, различные числовые данные, типа длинны пакета должны быть в сетевом представлении, т.е. на них перед записью в пакет надо натравливать htons
Автор: butcher    Оценить