vesago 0 9 октября, 2006 Опубликовано 9 октября, 2006 · Жалоба Пытаюсь на меге гонять данные через GPRS. Не стал я пользовать готовые стеки типа айпи и лвп. Пишу свое приложение - порезаный tcp на нет. Так вот вопрос к тем кто разбирался с этой тематикой. Как правильно посчитать контрольную сумму для TCP пакета? Смотрел я упомянутые стеки. там для IP и TCP пакета вроде одинаковый алгоритм. Я позаимствовал их код. Снифером смотрел сетевой трафик в локалке - для TCP такой вариант не проходит - не сходится контрольная сумма. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 9 октября, 2006 Опубликовано 9 октября, 2006 · Жалоба Пытаюсь на меге гонять данные через GPRS. Не стал я пользовать готовые стеки типа айпи и лвп. Пишу свое приложение - порезаный tcp на нет. Так вот вопрос к тем кто разбирался с этой тематикой. Как правильно посчитать контрольную сумму для TCP пакета? Смотрел я упомянутые стеки. там для IP и TCP пакета вроде одинаковый алгоритм. Я позаимствовал их код. Снифером смотрел сетевой трафик в локалке - для TCP такой вариант не проходит - не сходится контрольная сумма. А ты не забыл, что в TCP есть еще псевдо-заголовок, который участвует в подсчете контрольной суммы, но не передается в канал связи? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vesago 0 9 октября, 2006 Опубликовано 9 октября, 2006 · Жалоба Не забыл. Я перед расчетом инициализирую чексум числом 6 + длина TCP и натравляю процедуру на начало IP адресов в буфере. Попробовал за основу взять расчет IP чексум, но менять порядок 16 битных данных. Стала сходиться. Можно было-бы забить. но где гарантия, что в другой среде не будет проблем. Еще посомтрел в микроайпи и лвайпи не меняется порядок. Да и статью почитал одну в которой сказано, что от изменения порядка 16 битных опрерандов контрольной суммы изменяется толькло порядок байтов результата. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ktod 0 9 октября, 2006 Опубликовано 9 октября, 2006 (изменено) · Жалоба Делаю так: inline u16 checksum(u8* d, int l, u32 c) { while(l > 1) { c += *(u16*)d; d += 2; l -= 2; } if(l) c += *d; c = (c >> 16) + (c & 0xffff); c += (c >> 16); u16 ret = ((u16)(~c)); return ret; } где вызов: u32 ph = (saddr) & 0xffff) + ( (saddr) >> 16) + ((daddr) & 0xffff) + ((daddr) >> 16) + 0x600 + ((u16)l); u16 cs = checksum(d, l, ph); u32 saddr и пр. берется из ип хедера. Это для тсп. для удп: u32 ph = (saddr) & 0xffff) + ( (saddr) >> 16) + ((daddr) & 0xffff) + ((daddr) >> 16) + 0x1100 + ((u16)l); u16 cs = checksum(d, l, ph); для ип еще проще: u16 cs = checksum(d, ihl, 0); Не забываем, что для ип сумма считается только для заголовка. Изменено 9 октября, 2006 пользователем ktod Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vesago 0 10 октября, 2006 Опубликовано 10 октября, 2006 · Жалоба Спасибо, попробую. Увы не сходится. Я смотрел снифером пакет: volatile unsigned char buf[] = { 0xC0, 0xA8, 0x01, 0x08, //src addr 0xC0, 0xA8, 0x01, 0x0E, //dst addr 0x11, 0x42, 0x13, 0x88, //Сам TCP пакет всего 25 октетов 0x97, 0xD4, 0xA2, 0x11, 0x1B, 0x01, 0x1A, 0x63, 0x50, 0x18, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x31, 0x31, 0x31, 0x31, 0x31 }; Для него контрольная сумма 0x04EA. Может под нетбиосом как-то по другому считается? Зато контрольная сумма сходится если посчитать этой процедуро предварительно tcp_crc = 6 + 25. void Calc_TCP_CRC(unsigned char *buf, unsigned int len, unsigned int *tcp_crc) { unsigned long crc = *tcp_crc; unsigned int *ptr_to_buf = (unsigned int*)buf; unsigned int i, tmp; i = 0; do { tmp = (*(ptr_to_buf))>>8; tmp += (*(ptr_to_buf++))<<8; crc += tmp; i += 2; }while(i<len); if((len/2) & 1) crc += *((unsigned char*)ptr_to_buf); crc = (crc >> 16) + crc & 0xffff; crc += (crc >> 16); crc=(unsigned int)(~crc); *tcp_crc = (unsigned int)crc; } volatile unsigned int tcp_crc = 6 + 25; Calc_TCP_CRC((unsigned char *)&buf, 33, (unsigned int *)&tcp_crc); По сути дела она работает как и ваша. Просто хотелось бы иметь одну процедуру. которая считала бы и для IP и для TCP как в вашем случае. в приаттаченой статье тоже говорится что одна функция. Не могу понять чего у меня не работает. ___________________________________TCPIP.zip Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ktod 0 10 октября, 2006 Опубликовано 10 октября, 2006 (изменено) · Жалоба Обратите внимание на 0x600 + ((u16)l) при расчете для тсп. l - это длинна тсп пакета. т.е. длина используется два раза при расчете кс. По сути дела строкой volatile unsigned int tcp_crc = 6 + 25; Вы это и делаете. И если посмотреть на весь ip пакет будет понятно откуда взялось 0x600. ЗЫ: Поищите другое описание тсп. Приведенное Вами, несколько сумбурное. Изменено 10 октября, 2006 пользователем ktod Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vesago 0 11 октября, 2006 Опубликовано 11 октября, 2006 · Жалоба Статья конечно не основание. Я почитываю соответствующий RFC. В статье просто некоторые ньюансы рассмотрены. В частности сказано, что как и вашем коде процедура расчета чексум общая для всех частей IP пакета. Но вот у меня не получается хоть тресни. Не могу понять почему у вас работает и в фриварных стеках. Наверное забью я на эту общую чексум и буду пользовать для каждо части свою процедуру. По крайней мере так сходится. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 11 октября, 2006 Опубликовано 11 октября, 2006 · Жалоба Шепну по секрету, что очень уж долгая песня расчет CRC в 32-битном варианте - много загрузок, много регистров требуется... Поэтому лично я набрался наглости сделать так: unsigned int rxcrc; #pragma optimize=no_inline void subrxcrc(unsigned int i) { i=rxcrc-i; if (_CARRY) i--; rxcrc=i; } Имеется в виду добавление одного слова к CRC. На код стало куда более приятно смотреть... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vesago 0 11 октября, 2006 Опубликовано 11 октября, 2006 · Жалоба Недурственная идея. А сам алгоритм у вас как вышерассмотренный? Используете тоже одну функцию для всех частей IP пакета? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 11 октября, 2006 Опубликовано 11 октября, 2006 · Жалоба Недурственная идея. А сам алгоритм у вас как вышерассмотренный? Используете тоже одну функцию для всех частей IP пакета? Ох... Там через одно место для экономии... Так что прицепляю исходники моего TCP/IP стека через SLIP uNikeTCP.zip... Почитайте, может чего полезного извлечете... Есть там пара фишек типа переключения контекстов через setjmp/longjmp и т.д. Сделано под IAR.uNikeTCP.zip Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vesago 0 11 октября, 2006 Опубликовано 11 октября, 2006 · Жалоба Спасибо. Очень интересный код - вроде маленькой оси. Оказывается в яре есть функция смены порядка байтов __reverse. А я искал типа htons. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться