реклама на сайте
подробности

 
 
> tcp/ip
vesago
сообщение Oct 9 2006, 13:27
Сообщение #1


Тутэйшы
****

Группа: Свой
Сообщений: 708
Регистрация: 30-11-04
Пользователь №: 1 263



Пытаюсь на меге гонять данные через GPRS. Не стал я пользовать готовые стеки типа айпи и лвп. Пишу свое приложение - порезаный tcp на нет. Так вот вопрос к тем кто разбирался с этой тематикой. Как правильно посчитать контрольную сумму для TCP пакета? Смотрел я упомянутые стеки. там для IP и TCP пакета вроде одинаковый алгоритм. Я позаимствовал их код. Снифером смотрел сетевой трафик в локалке - для TCP такой вариант не проходит - не сходится контрольная сумма.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 10)
Rst7
сообщение Oct 9 2006, 14:46
Сообщение #2


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата(vesago @ Oct 9 2006, 16:27) *
Пытаюсь на меге гонять данные через GPRS. Не стал я пользовать готовые стеки типа айпи и лвп. Пишу свое приложение - порезаный tcp на нет. Так вот вопрос к тем кто разбирался с этой тематикой. Как правильно посчитать контрольную сумму для TCP пакета? Смотрел я упомянутые стеки. там для IP и TCP пакета вроде одинаковый алгоритм. Я позаимствовал их код. Снифером смотрел сетевой трафик в локалке - для TCP такой вариант не проходит - не сходится контрольная сумма.


А ты не забыл, что в TCP есть еще псевдо-заголовок, который участвует в подсчете контрольной суммы, но не передается в канал связи?


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
vesago
сообщение Oct 9 2006, 15:25
Сообщение #3


Тутэйшы
****

Группа: Свой
Сообщений: 708
Регистрация: 30-11-04
Пользователь №: 1 263



Не забыл. Я перед расчетом инициализирую чексум числом 6 + длина TCP и натравляю процедуру на начало IP адресов в буфере. Попробовал за основу взять расчет IP чексум, но менять порядок 16 битных данных. Стала сходиться. Можно было-бы забить. но где гарантия, что в другой среде не будет проблем. Еще посомтрел в микроайпи и лвайпи не меняется порядок. Да и статью почитал одну в которой сказано, что от изменения порядка 16 битных опрерандов контрольной суммы изменяется толькло порядок байтов результата.
Go to the top of the page
 
+Quote Post
ktod
сообщение Oct 9 2006, 16:40
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 27-09-05
Пользователь №: 8 979



Делаю так:
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);


Не забываем, что для ип сумма считается только для заголовка.

Сообщение отредактировал ktod - Oct 9 2006, 16:43


--------------------
Ignoramus et Ignorabimus
Go to the top of the page
 
+Quote Post
vesago
сообщение Oct 10 2006, 08:54
Сообщение #5


Тутэйшы
****

Группа: Свой
Сообщений: 708
Регистрация: 30-11-04
Пользователь №: 1 263



Спасибо, попробую.
Увы не сходится. Я смотрел снифером пакет:
Код
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 ( 19.1 килобайт ) Кол-во скачиваний: 49
 
Go to the top of the page
 
+Quote Post
ktod
сообщение Oct 10 2006, 15:40
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 27-09-05
Пользователь №: 8 979



Обратите внимание на 0x600 + ((u16)l) при расчете для тсп.
l - это длинна тсп пакета. т.е. длина используется два раза при расчете кс.

По сути дела строкой
volatile unsigned int tcp_crc = 6 + 25;
Вы это и делаете.

И если посмотреть на весь ip пакет будет понятно откуда взялось 0x600.

ЗЫ: Поищите другое описание тсп. Приведенное Вами, несколько сумбурное.

Сообщение отредактировал ktod - Oct 10 2006, 15:44


--------------------
Ignoramus et Ignorabimus
Go to the top of the page
 
+Quote Post
vesago
сообщение Oct 11 2006, 07:46
Сообщение #7


Тутэйшы
****

Группа: Свой
Сообщений: 708
Регистрация: 30-11-04
Пользователь №: 1 263



Статья конечно не основание. Я почитываю соответствующий RFC. В статье просто некоторые ньюансы рассмотрены. В частности сказано, что как и вашем коде процедура расчета чексум общая для всех частей IP пакета. Но вот у меня не получается хоть тресни. Не могу понять почему у вас работает и в фриварных стеках. Наверное забью я на эту общую чексум и буду пользовать для каждо части свою процедуру. По крайней мере так сходится.
Go to the top of the page
 
+Quote Post
Rst7
сообщение Oct 11 2006, 07:46
Сообщение #8


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Шепну по секрету, что очень уж долгая песня расчет CRC в 32-битном варианте - много загрузок, много регистров требуется... Поэтому лично я набрался наглости сделать так:
Код
unsigned int rxcrc;

#pragma optimize=no_inline
void subrxcrc(unsigned int i)
{
i=rxcrc-i;
if (_CARRY) i--;
rxcrc=i;
}


Имеется в виду добавление одного слова к CRC.

На код стало куда более приятно смотреть...


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
vesago
сообщение Oct 11 2006, 08:28
Сообщение #9


Тутэйшы
****

Группа: Свой
Сообщений: 708
Регистрация: 30-11-04
Пользователь №: 1 263



Недурственная идея. А сам алгоритм у вас как вышерассмотренный? Используете тоже одну функцию для всех частей IP пакета?
Go to the top of the page
 
+Quote Post
Rst7
сообщение Oct 11 2006, 09:38
Сообщение #10


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата(vesago @ Oct 11 2006, 11:28) *
Недурственная идея. А сам алгоритм у вас как вышерассмотренный? Используете тоже одну функцию для всех частей IP пакета?


Ох... Там через одно место для экономии... Так что прицепляю исходники моего TCP/IP стека через SLIP Прикрепленный файл  uNikeTCP.zip ( 14.35 килобайт ) Кол-во скачиваний: 247
... Почитайте, может чего полезного извлечете... Есть там пара фишек типа переключения контекстов через setjmp/longjmp и т.д. Сделано под IAR.Прикрепленный файл  uNikeTCP.zip ( 14.35 килобайт ) Кол-во скачиваний: 247


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
vesago
сообщение Oct 11 2006, 11:07
Сообщение #11


Тутэйшы
****

Группа: Свой
Сообщений: 708
Регистрация: 30-11-04
Пользователь №: 1 263



Спасибо. Очень интересный код - вроде маленькой оси. Оказывается в яре есть функция смены порядка байтов __reverse. А я искал типа htons.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 20:40
Рейтинг@Mail.ru


Страница сгенерированна за 0.0143 секунд с 7
ELECTRONIX ©2004-2016